3.8 CORDIC The CORDIC provides hardware acceleration of certain mathematical functions, notably trigonometric, commonly used in motor control, metering, signal processing and many other applications. It speeds up the calculation of these functions compared to a software implementation, allowing a lower operating frequency, or freeing up processor cycles in order to perform other tasks. Cordic features • 24-bit CORDIC rotation engine • Circular and Hyperbolic modes • Rotation and Vectoring modes • Functions: Sine, Cosine, Sinh, Cosh, Atan, Atan2, Atanh, Modulus, Square root, Natural logarithm • Programmable precision up to 20-bit • Fast convergence: 4 bits per clock cycle • Supports 16-bit and 32-bit fixed point input and output formats • Low latency AHB slave interface • Results can be read as soon as ready without polling or interrupt • DMA read and write channels
3.9 Filter mathematical accelerator (FMAC) The filter mathematical accelerator unit performs arithmetic operations on vectors. It comprises a multiplier/accumulator (MAC) unit, together with address generation logic, which allows it to index vector elements held in local memory. The unit includes support for circular buffers on input and output, which allows digital filters to be implemented. Both finite and infinite impulse response filters can be realized. The unit allows frequent or lengthy filtering operations to be offloaded from the CPU, freeing up the processor for other tasks. In many cases it can accelerate such calculations compared to a software implementation, resulting in a speed-up of time critical tasks. FMAC features • 16 x 16-bit multiplier • 24+2-bit accumulator with addition and subtraction • 16-bit input and output data • 256 x 16-bit local memory • Up to three areas can be defined in memory for data buffers (two input, one output), defined by programmable base address pointers and associated size registers • Input and output sample buffers can be circular • Buffer “watermark” feature reduces overhead in interrupt mode • Filter functions: FIR, IIR (direct form 1) • AHB slave interface • DMA read and write data channels
1. Configure the CORDIC: LL_CORDIC_Config( CORDIC, LL_CORDIC_FUNCTION_COSINE, /* cosine function */ LL_CORDIC_PRECISION_6CYCLES, /* max precision for q1.31 cosine */ LL_CORDIC_SCALE_0, /* no scale */ LL_CORDIC_NBWRITE_1, /* One input data: angle. Second input data (modulus) is 1 af ter cordic reset */ LL_CORDIC_NBREAD_2, /* Two output data: cosine, then sine */ LL_CORDIC_INSIZE_32BITS, /* q1.31 format for input data */ LL_CORDIC_OUTSIZE_32BITS ); /* q1.31 format for output data */ If only this configuration is used, this step is done once at initialization. Otherwise, it must be repeated each time one of the above parameters changes. 2. Write the input argument(s): /* Write angle */ LL_CORDIC_WriteData(CORDIC, ANGLE_CORDIC); In this case, there is only one argument, the angle (defined as a constant value π/8). The other argument is the default modulus of 1, so does not need to be written. As soon as the expected number of arguments is written, the calculation starts. 3. Read the result(s): /* Read cosine */ cosOutput = (int32_t)LL_CORDIC_ReadData(CORDIC); /* Read sine */ sinOutput = (int32_t)LL_CORDIC_ReadData(CORDIC);
FMAC configuration The FMAC can be configured using the HAL driver from the STM32CubeG4 MCU Package. Before accessing any FMAC registers, the FMAC clock must be enabled: __HAL_RCC_FMAC_CLK_ENABLE(); An area of system memory must be reserved for the coefficients: /* Declare an array to hold the filter coefficients */ static int16_t aFilterCoeffB[51]; We must also declare a structure to contain the FMAC parameters: FMAC_HandleTypeDef hfmac; Now we can configure the FMAC using the HAL_FMAC_FilterConfig() function: FMAC_FilterConfigTypeDef sFmacConfig; /* declare a filter configuration structure */ sFmacConfig.CoeffBaseAddress = 0; /* Set the coefficient buffer base address */ sFmacConfig.CoeffBufferSize = 51; /* Set the coefficient buffer size to the number of coeffs */ sFmacConfig.InputBaseAddress = 51; /* Set the Input buffer base address to the next free address */ sFmacConfig.InputBufferSize = 100; /* Set the input buffer size greater than the number of coeffs */ sFmacConfig.InputThreshold = 0; /* Set the input watermark to zero since we are using DMA */ sFmacConfig.OutputBaseAddress = 151; /* Set the Output buffer base address to the next free address */ sFmacConfig.OutputBufferSize = 100; /* Set the output buffer size */ sFmacConfig.OutputThreshold = 0; /* Set the output watermark to zero since we are using DMA */ /* No A coefficients since FIR */ sFmacConfig.pCoeffA = NULL; sFmacConfig.CoeffASize = 0; sFmacConfig.pCoeffB = aFilterCoeffB; /* Pointer to the coefficients in memory */ sFmacConfig.CoeffBSize = 51; /* Number of coefficients */ sFmacConfig.Filter = FMAC_FUNC_CONVO_FIR; /* Select FIR filter function */ sFmacConfig.InputAccess = FMAC_BUFFER_ACCESS_DMA; /* Enable DMA input transfer */ sFmacConfig.OutputAccess = FMAC_BUFFER_ACCESS_DMA; /* Enable DMA output transfer */ sFmacConfig.Clip = FMAC_CLIP_ENABLED; /* Enable clipping of the output at 0x7FFF and 0x8000 */ sFmacConfig.P = 51; /* P parameter contains number of coefficients */ sFmacConfig.Q = FILTER_PARAM_Q_NOT_USED; /* Q parameter is not used */ sFmacConfig.R = 0; /* R parameter contains the post-shift value (none) */ if (HAL_FMAC_FilterConfig(&hfmac, &sFmacConfig) != HAL_OK) /* Configure the FMAC */ Error_Handler(); /* Configuration Error */ The HAL_FMAC_FilterConfig() function programs the configuration and control registers, and loads the coefficients into the FMAC local memory (X2 buffer).
전압이 이상하게(?) 낮게 나와서 찾아 보는데 (대충 0.3v 정도?) gpt도 캘리브레이션 하라고 한다.
cubeide에 의해서 생성된 코드로 adc 가 초기화되고 나서
캘리브레이션 한 다음 약 2usec 이후에 HAL_ADC_GetValue(&hadc1); 하면 된다고 한다.
MX_ADC1_Init(); /* USER CODE BEGIN 2 */ extern ADC_HandleTypeDef hadc1; HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED); HAL_Delay(2); /* USER CODE END 2 */
/* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) {
[ 50.788963] usb 1-1.1: new full-speed USB device number 4 using ehci-pci [ 50.853992] usb 1-1.1: device descriptor read/64, error -32 [ 51.023960] usb 1-1.1: device descriptor read/64, error -32 [ 51.196938] usb 1-1.1: new full-speed USB device number 5 using ehci-pci [ 51.261946] usb 1-1.1: device descriptor read/64, error -32 [ 51.429943] usb 1-1.1: device descriptor read/64, error -32 [ 51.533019] usb 1-1-port1: attempt power cycle [ 52.113007] usb 1-1.1: new full-speed USB device number 6 using ehci-pci [ 52.524932] usb 1-1.1: device not accepting address 6, error -32 [ 52.589928] usb 1-1.1: new full-speed USB device number 7 using ehci-pci [ 53.004924] usb 1-1.1: device not accepting address 7, error -32 [ 53.005142] usb 1-1-port1: unable to enumerate USB device
boot0 - 1 / boot1 - 0에 usb 연결. 차이는 없다.
[ 225.014866] usb 1-1.1: new full-speed USB device number 8 using ehci-pci [ 225.079866] usb 1-1.1: device descriptor read/64, error -32 [ 225.253817] usb 1-1.1: device descriptor read/64, error -32 [ 225.420787] usb 1-1.1: new full-speed USB device number 9 using ehci-pci [ 225.485801] usb 1-1.1: device descriptor read/64, error -32 [ 225.654762] usb 1-1.1: device descriptor read/64, error -32 [ 225.756872] usb 1-1-port1: attempt power cycle [ 226.337664] usb 1-1.1: new full-speed USB device number 10 using ehci-pci [ 226.756996] usb 1-1.1: device not accepting address 10, error -32 [ 226.820602] usb 1-1.1: new full-speed USB device number 11 using ehci-pci [ 227.236577] usb 1-1.1: device not accepting address 11, error -32 [ 227.236751] usb 1-1-port1: unable to enumerate USB device
일단 PA9이 USART1_TX / PA10이 USART1_RX니까 USB TTL을 이용해서 적당히 연결해줘본다.
Interface serial_posix: 57600 8E1 Warning: the interface was not closed properly. Version : 0x30 Option 1 : 0x00 Option 2 : 0x00 Device ID : 0x0410 (STM32F10xxx Medium-density) - RAM : Up to 20KiB (512b reserved by bootloader) - Flash : Up to 128KiB (size first sector: 4x1024) - Option RAM : 16b - System RAM : 2KiB
프로그램이 없어서 그런가 boot0 - 0, boot1 - 0 으로 되어있어도 내부 부트로더가 작동한다.