adding in code
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
#include <Wire.h>
|
||||
#include "PAJ7620U2.h"
|
||||
|
||||
unsigned short Gesture_Data;
|
||||
void setup() {
|
||||
uint8_t i;
|
||||
Serial.begin(115200);
|
||||
Serial.print("\nGesture Sensor Test Program ...\n");
|
||||
delayMicroseconds(800);
|
||||
Wire.begin();
|
||||
delayMicroseconds(10);
|
||||
while(!PAJ7620U2_init())
|
||||
{ Serial.print("\nGesture Sensor Error\n");
|
||||
delay(500);
|
||||
}
|
||||
Serial.print("\nGesture Sensor OK\n");
|
||||
I2C_writeByte(PAJ_BANK_SELECT, 0);//Select Bank 0
|
||||
for (i = 0; i < Gesture_Array_SIZE; i++)
|
||||
{
|
||||
I2C_writeByte(Init_Gesture_Array[i][0], Init_Gesture_Array[i][1]);//Gesture register initializes
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Gesture_Data = I2C_readU16(PAJ_INT_FLAG1);
|
||||
if (Gesture_Data)
|
||||
{
|
||||
switch (Gesture_Data)
|
||||
{
|
||||
case PAJ_UP: Serial.print("Up\r\n"); break;
|
||||
case PAJ_DOWN: Serial.print("Down\r\n"); break;
|
||||
case PAJ_LEFT: Serial.print("Left\r\n"); break;
|
||||
case PAJ_RIGHT: Serial.print("Right\r\n"); break;
|
||||
case PAJ_FORWARD: Serial.print("Forward\r\n"); break;
|
||||
case PAJ_BACKWARD: Serial.print("Backward\r\n"); break;
|
||||
case PAJ_CLOCKWISE: Serial.print("Clockwise\r\n"); break;
|
||||
case PAJ_COUNT_CLOCKWISE: Serial.print("AntiClockwise\r\n"); break;
|
||||
case PAJ_WAVE: Serial.print("Wave\r\n"); break;
|
||||
default: break;
|
||||
}
|
||||
Gesture_Data=0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#include "PAJ7620U2.h"
|
||||
|
||||
|
||||
|
||||
uint8_t I2C_readByte(uint8_t addr)
|
||||
{
|
||||
Wire.beginTransmission(PAJ7620U2_I2C_ADDRESS);
|
||||
Wire.write(addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(PAJ7620U2_I2C_ADDRESS, 1);
|
||||
if (Wire.available()) {
|
||||
return Wire.read();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
uint16_t I2C_readU16(uint8_t addr)
|
||||
{
|
||||
uint16_t x; uint16_t t;
|
||||
|
||||
Wire.beginTransmission(PAJ7620U2_I2C_ADDRESS);
|
||||
Wire.write(addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(PAJ7620U2_I2C_ADDRESS, 2);
|
||||
t = Wire.read();
|
||||
x = Wire.read();
|
||||
x <<= 8;
|
||||
x |= t;
|
||||
return x;
|
||||
}
|
||||
void I2C_writeByte(uint8_t addr, uint8_t data)
|
||||
{
|
||||
Wire.beginTransmission(PAJ7620U2_I2C_ADDRESS);
|
||||
Wire.write(addr);
|
||||
Wire.write(data & 0xFF);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
uint8_t PAJ7620U2_init()
|
||||
{
|
||||
uint8_t i,State;
|
||||
State =I2C_readByte(0x00); //Read State
|
||||
if (State != 0x20) return 0; //Wake up failed
|
||||
I2C_writeByte(PAJ_BANK_SELECT, 0); //Select Bank 0
|
||||
for (i=0;i< Init_Array;i++)
|
||||
{
|
||||
I2C_writeByte(Init_Register_Array[i][0], Init_Register_Array[i][1]);//Power up initialize
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
#ifndef _PAJ7620U2_
|
||||
#define _PAJ7620U2_
|
||||
|
||||
//i2c address
|
||||
#define PAJ7620U2_I2C_ADDRESS 0x73
|
||||
//Register Bank select
|
||||
#define PAJ_BANK_SELECT 0xEF /*Bank0=0x00,Bank1=0x01*/
|
||||
//Register Bank 0
|
||||
#define PAJ_SUSPEND 0x03 /*I2C suspend command (Write 0x01 to enter suspend state). I2C wake-up command is slave ID wake-up. Refer to topic ��I2C Bus Timing Characteristics and Protocol��*/
|
||||
#define PAJ_INT_FLAG1_MASK 0x41 /*Gesture detection interrupt flag mask*/
|
||||
#define PAJ_INT_FLAG2_MASK 0x42 /*Gesture/PS detection interrupt flag mask*/
|
||||
#define PAJ_INT_FLAG1 0x43 /*Gesture detection interrupt flag*/
|
||||
#define PAJ_INT_FLAG2 0x44 /*Gesture/PS detection interrupt flag*/
|
||||
#define PAJ_STATE 0x45 /*State indicator for gesture detection (Only functional at gesture detection mode)*/
|
||||
#define PAJ_PS_HIGH_THRESHOLD 0x69 /*PS hysteresis high threshold (Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_LOW_THRESHOLD 0x6A /*PS hysteresis low threshold (Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_APPROACH_STATE 0x6B /*PS approach state, Approach = 1 , (8 bits PS data >= PS high threshold), Not Approach = 0 , (8 bits PS data <= PS low threshold)(Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_DATA 0x6C /*PS 8 bit data(Only functional at gesture detection mode)*/
|
||||
#define PAJ_OBJ_BRIGHTNESS 0xB0 /*Object Brightness (Max. 255)*/
|
||||
#define PAJ_OBJ_SIZE_L 0xB1 /*Object Size(Low 8 bit)*/
|
||||
#define PAJ_OBJ_SIZE_H 0xB2 /*Object Size(High 8 bit)*/
|
||||
|
||||
//Register Bank 1
|
||||
#define PAJ_PS_GAIN 0x44 /*PS gain setting (Only functional at proximity detection mode)*/
|
||||
#define PAJ_IDLE_S1_STEP_L 0x67 /*IDLE S1 Step, for setting the S1, Response Factor(Low 8 bit)*/
|
||||
#define PAJ_IDLE_S1_STEP_H 0x68 /*IDLE S1 Step, for setting the S1, Response Factor(High 8 bit)*/
|
||||
#define PAJ_IDLE_S2_STEP_L 0x69 /*IDLE S2 Step, for setting the S2, Response Factor(Low 8 bit)*/
|
||||
#define PAJ_IDLE_S2_STEP_H 0x6A /*IDLE S2 Step, for setting the S2, Response Factor(High 8 bit)*/
|
||||
#define PAJ_OPTOS1_TIME_L 0x6B /*OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 state(Low 8 bit)*/
|
||||
#define PAJ_OPTOS2_TIME_H 0x6C /*OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 stateHigh 8 bit)*/
|
||||
#define PAJ_S1TOS2_TIME_L 0x6D /*S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 state(Low 8 bit)*/
|
||||
#define PAJ_S1TOS2_TIME_H 0x6E /*S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 stateHigh 8 bit)*/
|
||||
#define PAJ_EN 0x72 /*Enable/Disable PAJ7620U2*/
|
||||
//Gesture detection interrupt flag
|
||||
#define PAJ_UP 0x01
|
||||
#define PAJ_DOWN 0x02
|
||||
#define PAJ_LEFT 0x04
|
||||
#define PAJ_RIGHT 0x08
|
||||
#define PAJ_FORWARD 0x10
|
||||
#define PAJ_BACKWARD 0x20
|
||||
#define PAJ_CLOCKWISE 0x40
|
||||
#define PAJ_COUNT_CLOCKWISE 0x80
|
||||
#define PAJ_WAVE 0x100
|
||||
//Initialize array size
|
||||
#define Init_Array sizeof(Init_Register_Array)/2
|
||||
#define PS_Array_SIZE sizeof(Init_PS_Array)/2
|
||||
#define Gesture_Array_SIZE sizeof(Init_Gesture_Array)/2
|
||||
//Power up initialize array
|
||||
const unsigned char Init_Register_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x37,0x07},
|
||||
{0x38,0x17},
|
||||
{0x39,0x06},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0x46,0x2D},
|
||||
{0x47,0x0F},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x4A,0x1E},
|
||||
{0x4C,0x20},
|
||||
{0x51,0x10},
|
||||
{0x5E,0x10},
|
||||
{0x60,0x27},
|
||||
{0x80,0x42},
|
||||
{0x81,0x44},
|
||||
{0x82,0x04},
|
||||
{0x8B,0x01},
|
||||
{0x90,0x06},
|
||||
{0x95,0x0A},
|
||||
{0x96,0x0C},
|
||||
{0x97,0x05},
|
||||
{0x9A,0x14},
|
||||
{0x9C,0x3F},
|
||||
{0xA5,0x19},
|
||||
{0xCC,0x19},
|
||||
{0xCD,0x0B},
|
||||
{0xCE,0x13},
|
||||
{0xCF,0x64},
|
||||
{0xD0,0x21},
|
||||
{0xEF,0x01},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x25,0x01},
|
||||
{0x27,0x39},
|
||||
{0x28,0x7F},
|
||||
{0x29,0x08},
|
||||
{0x3E,0xFF},
|
||||
{0x5E,0x3D},
|
||||
{0x65,0x96},
|
||||
{0x67,0x97},
|
||||
{0x69,0xCD},
|
||||
{0x6A,0x01},
|
||||
{0x6D,0x2C},
|
||||
{0x6E,0x01},
|
||||
{0x72,0x01},
|
||||
{0x73,0x35},
|
||||
{0x74,0x00},
|
||||
{0x77,0x01},
|
||||
};
|
||||
//Approaches register initialization array
|
||||
const unsigned char Init_PS_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x51,0x13},
|
||||
{0x83,0x20},
|
||||
{0x84,0x20},
|
||||
{0x85,0x00},
|
||||
{0x86,0x10},
|
||||
{0x87,0x00},
|
||||
{0x88,0x05},
|
||||
{0x89,0x18},
|
||||
{0x8A,0x10},
|
||||
{0x9f,0xf8},
|
||||
{0x69,0x96},
|
||||
{0x6A,0x02},
|
||||
{0xEF,0x01},
|
||||
{0x01,0x1E},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x41,0x50},
|
||||
{0x43,0x34},
|
||||
{0x65,0xCE},
|
||||
{0x66,0x0B},
|
||||
{0x67,0xCE},
|
||||
{0x68,0x0B},
|
||||
{0x69,0xE9},
|
||||
{0x6A,0x05},
|
||||
{0x6B,0x50},
|
||||
{0x6C,0xC3},
|
||||
{0x6D,0x50},
|
||||
{0x6E,0xC3},
|
||||
{0x74,0x05},
|
||||
};
|
||||
|
||||
//Gesture register initializes array
|
||||
const unsigned char Init_Gesture_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0xEF,0x00},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x51,0x10},
|
||||
{0x83,0x20},
|
||||
{0x9F,0xF9},
|
||||
{0xEF,0x01},
|
||||
{0x01,0x1E},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x41,0x40},
|
||||
{0x43,0x30},
|
||||
{0x65,0x96},
|
||||
{0x66,0x00},
|
||||
{0x67,0x97},
|
||||
{0x68,0x01},
|
||||
{0x69,0xCD},
|
||||
{0x6A,0x01},
|
||||
{0x6B,0xB0},
|
||||
{0x6C,0x04},
|
||||
{0x6D,0x2C},
|
||||
{0x6E,0x01},
|
||||
{0x74,0x00},
|
||||
{0xEF,0x00},
|
||||
{0x41,0xFF},
|
||||
{0x42,0x01},
|
||||
};
|
||||
uint8_t I2C_readByte(uint8_t addr);
|
||||
uint16_t I2C_readU16(uint8_t addr);
|
||||
void I2C_writeByte(uint8_t add, uint8_t data);
|
||||
uint8_t PAJ7620U2_init();
|
||||
#endif
|
||||
@@ -0,0 +1,50 @@
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#include "PAJ7620U2.h"
|
||||
|
||||
|
||||
|
||||
uint8_t I2C_readByte(uint8_t addr)
|
||||
{
|
||||
Wire.beginTransmission(PAJ7620U2_I2C_ADDRESS);
|
||||
Wire.write(addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(PAJ7620U2_I2C_ADDRESS, 1);
|
||||
if (Wire.available()) {
|
||||
return Wire.read();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
uint16_t I2C_readU16(uint8_t addr)
|
||||
{
|
||||
uint16_t x; uint16_t t;
|
||||
|
||||
Wire.beginTransmission(PAJ7620U2_I2C_ADDRESS);
|
||||
Wire.write(addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(PAJ7620U2_I2C_ADDRESS, 2);
|
||||
t = Wire.read();
|
||||
x = Wire.read();
|
||||
x <<= 8;
|
||||
x |= t;
|
||||
return x;
|
||||
}
|
||||
void I2C_writeByte(uint8_t addr, uint8_t data)
|
||||
{
|
||||
Wire.beginTransmission(PAJ7620U2_I2C_ADDRESS);
|
||||
Wire.write(addr);
|
||||
Wire.write(data & 0xFF);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
uint8_t PAJ7620U2_init()
|
||||
{
|
||||
uint8_t i,State;
|
||||
State =I2C_readByte(0x00); //Read State
|
||||
if (State != 0x20) return 0; //Wake up failed
|
||||
I2C_writeByte(PAJ_BANK_SELECT, 0); //Select Bank 0
|
||||
for (i=0;i< Init_Array;i++)
|
||||
{
|
||||
I2C_writeByte(Init_Register_Array[i][0], Init_Register_Array[i][1]);//Power up initialize
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
#ifndef _PAJ7620U2_
|
||||
#define _PAJ7620U2_
|
||||
|
||||
//i2c address
|
||||
#define PAJ7620U2_I2C_ADDRESS 0x73
|
||||
//Register Bank select
|
||||
#define PAJ_BANK_SELECT 0xEF /*Bank0=0x00,Bank1=0x01*/
|
||||
//Register Bank 0
|
||||
#define PAJ_SUSPEND 0x03 /*I2C suspend command (Write 0x01 to enter suspend state). I2C wake-up command is slave ID wake-up. Refer to topic ��I2C Bus Timing Characteristics and Protocol��*/
|
||||
#define PAJ_INT_FLAG1_MASK 0x41 /*Gesture detection interrupt flag mask*/
|
||||
#define PAJ_INT_FLAG2_MASK 0x42 /*Gesture/PS detection interrupt flag mask*/
|
||||
#define PAJ_INT_FLAG1 0x43 /*Gesture detection interrupt flag*/
|
||||
#define PAJ_INT_FLAG2 0x44 /*Gesture/PS detection interrupt flag*/
|
||||
#define PAJ_STATE 0x45 /*State indicator for gesture detection (Only functional at gesture detection mode)*/
|
||||
#define PAJ_PS_HIGH_THRESHOLD 0x69 /*PS hysteresis high threshold (Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_LOW_THRESHOLD 0x6A /*PS hysteresis low threshold (Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_APPROACH_STATE 0x6B /*PS approach state, Approach = 1 , (8 bits PS data >= PS high threshold), Not Approach = 0 , (8 bits PS data <= PS low threshold)(Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_DATA 0x6C /*PS 8 bit data(Only functional at gesture detection mode)*/
|
||||
#define PAJ_OBJ_BRIGHTNESS 0xB0 /*Object Brightness (Max. 255)*/
|
||||
#define PAJ_OBJ_SIZE_L 0xB1 /*Object Size(Low 8 bit)*/
|
||||
#define PAJ_OBJ_SIZE_H 0xB2 /*Object Size(High 8 bit)*/
|
||||
|
||||
//Register Bank 1
|
||||
#define PAJ_PS_GAIN 0x44 /*PS gain setting (Only functional at proximity detection mode)*/
|
||||
#define PAJ_IDLE_S1_STEP_L 0x67 /*IDLE S1 Step, for setting the S1, Response Factor(Low 8 bit)*/
|
||||
#define PAJ_IDLE_S1_STEP_H 0x68 /*IDLE S1 Step, for setting the S1, Response Factor(High 8 bit)*/
|
||||
#define PAJ_IDLE_S2_STEP_L 0x69 /*IDLE S2 Step, for setting the S2, Response Factor(Low 8 bit)*/
|
||||
#define PAJ_IDLE_S2_STEP_H 0x6A /*IDLE S2 Step, for setting the S2, Response Factor(High 8 bit)*/
|
||||
#define PAJ_OPTOS1_TIME_L 0x6B /*OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 state(Low 8 bit)*/
|
||||
#define PAJ_OPTOS2_TIME_H 0x6C /*OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 stateHigh 8 bit)*/
|
||||
#define PAJ_S1TOS2_TIME_L 0x6D /*S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 state(Low 8 bit)*/
|
||||
#define PAJ_S1TOS2_TIME_H 0x6E /*S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 stateHigh 8 bit)*/
|
||||
#define PAJ_EN 0x72 /*Enable/Disable PAJ7620U2*/
|
||||
//Gesture detection interrupt flag
|
||||
#define PAJ_UP 0x01
|
||||
#define PAJ_DOWN 0x02
|
||||
#define PAJ_LEFT 0x04
|
||||
#define PAJ_RIGHT 0x08
|
||||
#define PAJ_FORWARD 0x10
|
||||
#define PAJ_BACKWARD 0x20
|
||||
#define PAJ_CLOCKWISE 0x40
|
||||
#define PAJ_COUNT_CLOCKWISE 0x80
|
||||
#define PAJ_WAVE 0x100
|
||||
//Initialize array size
|
||||
#define Init_Array sizeof(Init_Register_Array)/2
|
||||
#define PS_Array_SIZE sizeof(Init_PS_Array)/2
|
||||
#define Gesture_Array_SIZE sizeof(Init_Gesture_Array)/2
|
||||
//Power up initialize array
|
||||
const unsigned char Init_Register_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x37,0x07},
|
||||
{0x38,0x17},
|
||||
{0x39,0x06},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0x46,0x2D},
|
||||
{0x47,0x0F},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x4A,0x1E},
|
||||
{0x4C,0x20},
|
||||
{0x51,0x10},
|
||||
{0x5E,0x10},
|
||||
{0x60,0x27},
|
||||
{0x80,0x42},
|
||||
{0x81,0x44},
|
||||
{0x82,0x04},
|
||||
{0x8B,0x01},
|
||||
{0x90,0x06},
|
||||
{0x95,0x0A},
|
||||
{0x96,0x0C},
|
||||
{0x97,0x05},
|
||||
{0x9A,0x14},
|
||||
{0x9C,0x3F},
|
||||
{0xA5,0x19},
|
||||
{0xCC,0x19},
|
||||
{0xCD,0x0B},
|
||||
{0xCE,0x13},
|
||||
{0xCF,0x64},
|
||||
{0xD0,0x21},
|
||||
{0xEF,0x01},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x25,0x01},
|
||||
{0x27,0x39},
|
||||
{0x28,0x7F},
|
||||
{0x29,0x08},
|
||||
{0x3E,0xFF},
|
||||
{0x5E,0x3D},
|
||||
{0x65,0x96},
|
||||
{0x67,0x97},
|
||||
{0x69,0xCD},
|
||||
{0x6A,0x01},
|
||||
{0x6D,0x2C},
|
||||
{0x6E,0x01},
|
||||
{0x72,0x01},
|
||||
{0x73,0x35},
|
||||
{0x74,0x00},
|
||||
{0x77,0x01},
|
||||
};
|
||||
//Approaches register initialization array
|
||||
const unsigned char Init_PS_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x51,0x13},
|
||||
{0x83,0x20},
|
||||
{0x84,0x20},
|
||||
{0x85,0x00},
|
||||
{0x86,0x10},
|
||||
{0x87,0x00},
|
||||
{0x88,0x05},
|
||||
{0x89,0x18},
|
||||
{0x8A,0x10},
|
||||
{0x9f,0xf8},
|
||||
{0x69,0x96},
|
||||
{0x6A,0x02},
|
||||
{0xEF,0x01},
|
||||
{0x01,0x1E},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x41,0x50},
|
||||
{0x43,0x34},
|
||||
{0x65,0xCE},
|
||||
{0x66,0x0B},
|
||||
{0x67,0xCE},
|
||||
{0x68,0x0B},
|
||||
{0x69,0xE9},
|
||||
{0x6A,0x05},
|
||||
{0x6B,0x50},
|
||||
{0x6C,0xC3},
|
||||
{0x6D,0x50},
|
||||
{0x6E,0xC3},
|
||||
{0x74,0x05},
|
||||
};
|
||||
|
||||
//Gesture register initializes array
|
||||
const unsigned char Init_Gesture_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0xEF,0x00},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x51,0x10},
|
||||
{0x83,0x20},
|
||||
{0x9F,0xF9},
|
||||
{0xEF,0x01},
|
||||
{0x01,0x1E},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x41,0x40},
|
||||
{0x43,0x30},
|
||||
{0x65,0x96},
|
||||
{0x66,0x00},
|
||||
{0x67,0x97},
|
||||
{0x68,0x01},
|
||||
{0x69,0xCD},
|
||||
{0x6A,0x01},
|
||||
{0x6B,0xB0},
|
||||
{0x6C,0x04},
|
||||
{0x6D,0x2C},
|
||||
{0x6E,0x01},
|
||||
{0x74,0x00},
|
||||
{0xEF,0x00},
|
||||
{0x41,0xFF},
|
||||
{0x42,0x01},
|
||||
};
|
||||
uint8_t I2C_readByte(uint8_t addr);
|
||||
uint16_t I2C_readU16(uint8_t addr);
|
||||
void I2C_writeByte(uint8_t add, uint8_t data);
|
||||
uint8_t PAJ7620U2_init();
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
#include <Wire.h>
|
||||
#include "PAJ7620U2.h"
|
||||
|
||||
unsigned short Gesture_Data;
|
||||
void setup() {
|
||||
uint8_t i;
|
||||
Serial.begin(115200);
|
||||
Serial.print("\nGesture Sensor Test Program ...\n");
|
||||
delayMicroseconds(800);
|
||||
Wire.begin();
|
||||
delayMicroseconds(10);
|
||||
while(!PAJ7620U2_init())
|
||||
{ Serial.print("\nGesture Sensor Error\n");
|
||||
delay(200);
|
||||
}
|
||||
Serial.print("\nGesture Sensor OK\n");
|
||||
I2C_writeByte(PAJ_BANK_SELECT, 0);//Select Bank 0
|
||||
for (i = 0; i < PS_Array_SIZE; i++)
|
||||
{
|
||||
I2C_writeByte(Init_PS_Array[i][0], Init_PS_Array[i][1]);//Gesture register initializes
|
||||
}
|
||||
I2C_writeByte(PAJ_BANK_SELECT, 0);
|
||||
}
|
||||
void loop() {
|
||||
uint8_t i, OBJ_BRIGHTNESS;
|
||||
unsigned short OBJ_SIZE;
|
||||
OBJ_BRIGHTNESS = I2C_readByte(PAJ_OBJ_BRIGHTNESS);
|
||||
OBJ_SIZE = I2C_readU16(PAJ_OBJ_SIZE_L);
|
||||
Serial.print("Object brightness = ");
|
||||
Serial.print(OBJ_BRIGHTNESS);
|
||||
Serial.print(" , ");
|
||||
Serial.print("Object size = ");
|
||||
Serial.print(OBJ_SIZE);
|
||||
Serial.print("\r\n");
|
||||
delay(300);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
PAJ7620U2:PAJ7620U2.c PAJ7620U2.h
|
||||
gcc -Wall PAJ7620U2.c -o PAJ7620U2 -lbcm2835 -lm
|
||||
clean:
|
||||
rm PAJ7620U2
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
#include <bcm2835.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "PAJ7620U2.h"
|
||||
/******************* PAJ7620U2 Driver Interface *****************************/
|
||||
char I2C_readByte(char reg)
|
||||
{
|
||||
char buf[] = { reg };
|
||||
bcm2835_i2c_read_register_rs(buf, buf, 1);
|
||||
return buf[0];
|
||||
}
|
||||
unsigned short I2C_readU16(char reg)
|
||||
{
|
||||
char buf[] = { reg,0 };
|
||||
bcm2835_i2c_read_register_rs(buf, buf, 2);
|
||||
int value = buf[1] * 0x100 + buf[0];
|
||||
return value;
|
||||
}
|
||||
void I2C_writeByte(char reg, char val)
|
||||
{
|
||||
char buf[] = { reg,val };
|
||||
bcm2835_i2c_write(buf, 2);
|
||||
}
|
||||
uint8_t PAJ7620U2_init()
|
||||
{
|
||||
uint8_t i,State;
|
||||
bcm2835_i2c_begin();
|
||||
bcm2835_i2c_setSlaveAddress(PAJ7620U2_I2C_ADDRESS);
|
||||
bcm2835_i2c_set_baudrate(10000);
|
||||
bcm2835_delay(5);
|
||||
State = I2C_readByte(0x00); //Read State
|
||||
if (State != 0x20) return 0; //Wake up failed
|
||||
I2C_writeByte(PAJ_BANK_SELECT, 0); //Select Bank 0
|
||||
for (i=0;i< Init_Array;i++)
|
||||
{
|
||||
I2C_writeByte(Init_Register_Array[i][0], Init_Register_Array[i][1]);//Power up initialize
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
uint8_t i;
|
||||
unsigned short Gesture_Data;
|
||||
printf("\nGesture Sensor Test Program ...\n");
|
||||
if (!bcm2835_init()) return 1;
|
||||
bcm2835_delay(5);
|
||||
if(!PAJ7620U2_init())
|
||||
{ printf("\nGesture Sensor Error\n");
|
||||
return 0;
|
||||
}
|
||||
printf("\nGesture Sensor OK\n");
|
||||
I2C_writeByte(PAJ_BANK_SELECT, 0);//Select Bank 0
|
||||
for (i = 0; i < Gesture_Array_SIZE; i++)
|
||||
{
|
||||
I2C_writeByte(Init_Gesture_Array[i][0], Init_Gesture_Array[i][1]);//Gesture register initializes
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
Gesture_Data = I2C_readU16(PAJ_INT_FLAG1);
|
||||
if (Gesture_Data)
|
||||
{
|
||||
switch (Gesture_Data)
|
||||
{
|
||||
case PAJ_UP: printf("Up\r\n"); break;
|
||||
case PAJ_DOWN: printf("Down\r\n"); break;
|
||||
case PAJ_LEFT: printf("Left\r\n"); break;
|
||||
case PAJ_RIGHT: printf("Right\r\n"); break;
|
||||
case PAJ_FORWARD: printf("Forward\r\n"); break;
|
||||
case PAJ_BACKWARD: printf("Backward\r\n"); break;
|
||||
case PAJ_CLOCKWISE: printf("Clockwise\r\n"); break;
|
||||
case PAJ_COUNT_CLOCKWISE: printf("AntiClockwise\r\n"); break;
|
||||
case PAJ_WAVE: printf("Wave\r\n"); break;
|
||||
default: break;
|
||||
}
|
||||
Gesture_Data=0;
|
||||
bcm2835_delay(50);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
#ifndef _PAJ7620U2_
|
||||
#define _PAJ7620U2_
|
||||
|
||||
//i2c address
|
||||
#define PAJ7620U2_I2C_ADDRESS 0x73
|
||||
//Register Bank select
|
||||
#define PAJ_BANK_SELECT 0xEF /*Bank0=0x00,Bank1=0x01*/
|
||||
//Register Bank 0
|
||||
#define PAJ_SUSPEND 0x03 /*I2C suspend command (Write 0x01 to enter suspend state). I2C wake-up command is slave ID wake-up. Refer to topic ¡°I2C Bus Timing Characteristics and Protocol¡±*/
|
||||
#define PAJ_INT_FLAG1_MASK 0x41 /*Gesture detection interrupt flag mask*/
|
||||
#define PAJ_INT_FLAG2_MASK 0x42 /*Gesture/PS detection interrupt flag mask*/
|
||||
#define PAJ_INT_FLAG1 0x43 /*Gesture detection interrupt flag*/
|
||||
#define PAJ_INT_FLAG2 0x44 /*Gesture/PS detection interrupt flag*/
|
||||
#define PAJ_STATE 0x45 /*State indicator for gesture detection (Only functional at gesture detection mode)*/
|
||||
#define PAJ_PS_HIGH_THRESHOLD 0x69 /*PS hysteresis high threshold (Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_LOW_THRESHOLD 0x6A /*PS hysteresis low threshold (Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_APPROACH_STATE 0x6B /*PS approach state, Approach = 1 , (8 bits PS data >= PS high threshold), Not Approach = 0 , (8 bits PS data <= PS low threshold)(Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_DATA 0x6C /*PS 8 bit data(Only functional at gesture detection mode)*/
|
||||
#define PAJ_OBJ_BRIGHTNESS 0xB0 /*Object Brightness (Max. 255)*/
|
||||
#define PAJ_OBJ_SIZE_L 0xB1 /*Object Size(Low 8 bit)*/
|
||||
#define PAJ_OBJ_SIZE_H 0xB2 /*Object Size(High 8 bit)*/
|
||||
|
||||
//Register Bank 1
|
||||
#define PAJ_PS_GAIN 0x44 /*PS gain setting (Only functional at proximity detection mode)*/
|
||||
#define PAJ_IDLE_S1_STEP_L 0x67 /*IDLE S1 Step, for setting the S1, Response Factor(Low 8 bit)*/
|
||||
#define PAJ_IDLE_S1_STEP_H 0x68 /*IDLE S1 Step, for setting the S1, Response Factor(High 8 bit)*/
|
||||
#define PAJ_IDLE_S2_STEP_L 0x69 /*IDLE S2 Step, for setting the S2, Response Factor(Low 8 bit)*/
|
||||
#define PAJ_IDLE_S2_STEP_H 0x6A /*IDLE S2 Step, for setting the S2, Response Factor(High 8 bit)*/
|
||||
#define PAJ_OPTOS1_TIME_L 0x6B /*OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 state(Low 8 bit)*/
|
||||
#define PAJ_OPTOS2_TIME_H 0x6C /*OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 stateHigh 8 bit)*/
|
||||
#define PAJ_S1TOS2_TIME_L 0x6D /*S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 state(Low 8 bit)*/
|
||||
#define PAJ_S1TOS2_TIME_H 0x6E /*S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 stateHigh 8 bit)*/
|
||||
#define PAJ_EN 0x72 /*Enable/Disable PAJ7620U2*/
|
||||
//Gesture detection interrupt flag
|
||||
#define PAJ_UP 0x01
|
||||
#define PAJ_DOWN 0x02
|
||||
#define PAJ_LEFT 0x04
|
||||
#define PAJ_RIGHT 0x08
|
||||
#define PAJ_FORWARD 0x10
|
||||
#define PAJ_BACKWARD 0x20
|
||||
#define PAJ_CLOCKWISE 0x40
|
||||
#define PAJ_COUNT_CLOCKWISE 0x80
|
||||
#define PAJ_WAVE 0x100
|
||||
//Initialize array size
|
||||
#define Init_Array sizeof(Init_Register_Array)/2
|
||||
#define PS_Array_SIZE sizeof(Init_PS_Array)/2
|
||||
#define Gesture_Array_SIZE sizeof(Init_Gesture_Array)/2
|
||||
//Power up initialize array
|
||||
unsigned char Init_Register_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x37,0x07},
|
||||
{0x38,0x17},
|
||||
{0x39,0x06},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0x46,0x2D},
|
||||
{0x47,0x0F},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x4A,0x1E},
|
||||
{0x4C,0x20},
|
||||
{0x51,0x10},
|
||||
{0x5E,0x10},
|
||||
{0x60,0x27},
|
||||
{0x80,0x42},
|
||||
{0x81,0x44},
|
||||
{0x82,0x04},
|
||||
{0x8B,0x01},
|
||||
{0x90,0x06},
|
||||
{0x95,0x0A},
|
||||
{0x96,0x0C},
|
||||
{0x97,0x05},
|
||||
{0x9A,0x14},
|
||||
{0x9C,0x3F},
|
||||
{0xA5,0x19},
|
||||
{0xCC,0x19},
|
||||
{0xCD,0x0B},
|
||||
{0xCE,0x13},
|
||||
{0xCF,0x64},
|
||||
{0xD0,0x21},
|
||||
{0xEF,0x01},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x25,0x01},
|
||||
{0x27,0x39},
|
||||
{0x28,0x7F},
|
||||
{0x29,0x08},
|
||||
{0x3E,0xFF},
|
||||
{0x5E,0x3D},
|
||||
{0x65,0x96},
|
||||
{0x67,0x97},
|
||||
{0x69,0xCD},
|
||||
{0x6A,0x01},
|
||||
{0x6D,0x2C},
|
||||
{0x6E,0x01},
|
||||
{0x72,0x01},
|
||||
{0x73,0x35},
|
||||
{0x74,0x00},
|
||||
{0x77,0x01},
|
||||
};
|
||||
//Approaches register initialization array
|
||||
unsigned char Init_PS_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x51,0x13},
|
||||
{0x83,0x20},
|
||||
{0x84,0x20},
|
||||
{0x85,0x00},
|
||||
{0x86,0x10},
|
||||
{0x87,0x00},
|
||||
{0x88,0x05},
|
||||
{0x89,0x18},
|
||||
{0x8A,0x10},
|
||||
{0x9f,0xf8},
|
||||
{0x69,0x96},
|
||||
{0x6A,0x02},
|
||||
{0xEF,0x01},
|
||||
{0x01,0x1E},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x41,0x50},
|
||||
{0x43,0x34},
|
||||
{0x65,0xCE},
|
||||
{0x66,0x0B},
|
||||
{0x67,0xCE},
|
||||
{0x68,0x0B},
|
||||
{0x69,0xE9},
|
||||
{0x6A,0x05},
|
||||
{0x6B,0x50},
|
||||
{0x6C,0xC3},
|
||||
{0x6D,0x50},
|
||||
{0x6E,0xC3},
|
||||
{0x74,0x05},
|
||||
};
|
||||
|
||||
//Gesture register initializes array
|
||||
const unsigned char Init_Gesture_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0xEF,0x00},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x51,0x10},
|
||||
{0x83,0x20},
|
||||
{0x9F,0xF9},
|
||||
{0xEF,0x01},
|
||||
{0x01,0x1E},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x41,0x40},
|
||||
{0x43,0x30},
|
||||
{0x65,0x96},
|
||||
{0x66,0x00},
|
||||
{0x67,0x97},
|
||||
{0x68,0x01},
|
||||
{0x69,0xCD},
|
||||
{0x6A,0x01},
|
||||
{0x6B,0xB0},
|
||||
{0x6C,0x04},
|
||||
{0x6D,0x2C},
|
||||
{0x6E,0x01},
|
||||
{0x74,0x00},
|
||||
{0xEF,0x00},
|
||||
{0x41,0xFF},
|
||||
{0x42,0x01},
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,5 @@
|
||||
PAJ7620U2:PAJ7620U2.c PAJ7620U2.h
|
||||
gcc -Wall PAJ7620U2.c -o PAJ7620U2 -lbcm2835 -lm
|
||||
clean:
|
||||
rm PAJ7620U2
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
#include <bcm2835.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "PAJ7620U2.h"
|
||||
/******************* PAJ7620U2 Driver Interface *****************************/
|
||||
char I2C_readByte(char reg)
|
||||
{
|
||||
char buf[] = { reg };
|
||||
bcm2835_i2c_read_register_rs(buf, buf, 1);
|
||||
return buf[0];
|
||||
}
|
||||
unsigned short I2C_readU16(char reg)
|
||||
{
|
||||
char buf[] = { reg,0 };
|
||||
bcm2835_i2c_read_register_rs(buf, buf, 2);
|
||||
int value = buf[1] * 0x100 + buf[0];
|
||||
return value;
|
||||
}
|
||||
void I2C_writeByte(char reg, char val)
|
||||
{
|
||||
char buf[] = { reg,val };
|
||||
bcm2835_i2c_write(buf, 2);
|
||||
}
|
||||
uint8_t PAJ7620U2_init()
|
||||
{
|
||||
uint8_t i,State;
|
||||
bcm2835_i2c_begin();
|
||||
bcm2835_i2c_setSlaveAddress(PAJ7620U2_I2C_ADDRESS);
|
||||
bcm2835_i2c_set_baudrate(10000);
|
||||
bcm2835_delay(5);
|
||||
State = I2C_readByte(0x00); //Read State
|
||||
if (State != 0x20) return 0; //Wake up failed
|
||||
I2C_writeByte(PAJ_BANK_SELECT, 0); //Select Bank 0
|
||||
for (i=0;i< Init_Array;i++)
|
||||
{
|
||||
I2C_writeByte(Init_Register_Array[i][0], Init_Register_Array[i][1]);//Power up initialize
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
uint8_t i, OBJ_BRIGHTNESS;
|
||||
unsigned short OBJ_SIZE;
|
||||
printf("\nGesture Sensor Test Program ...\n");
|
||||
if (!bcm2835_init()) return 1;
|
||||
bcm2835_delay(5);
|
||||
if(!PAJ7620U2_init())
|
||||
{ printf("\nGesture Sensor Error\n");
|
||||
return 0;
|
||||
}
|
||||
printf("\nGesture Sensor OK\n");
|
||||
I2C_writeByte(PAJ_BANK_SELECT, 0);//Select Bank 0
|
||||
for (i = 0; i < PS_Array_SIZE; i++)
|
||||
{
|
||||
I2C_writeByte(Init_PS_Array[i][0], Init_PS_Array[i][1]);//Gesture register initializes
|
||||
}
|
||||
I2C_writeByte(PAJ_BANK_SELECT, 0);
|
||||
while (1)
|
||||
{
|
||||
OBJ_BRIGHTNESS = I2C_readByte(PAJ_OBJ_BRIGHTNESS);
|
||||
OBJ_SIZE = I2C_readU16(PAJ_OBJ_SIZE_L);
|
||||
printf("Object brightness = %d ,Object size = %d\n", OBJ_BRIGHTNESS, OBJ_SIZE);//Object Brightness (Max. 255),Object Size (Max. 900)
|
||||
delay(50);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
#ifndef _PAJ7620U2_
|
||||
#define _PAJ7620U2_
|
||||
|
||||
//i2c address
|
||||
#define PAJ7620U2_I2C_ADDRESS 0x73
|
||||
//Register Bank select
|
||||
#define PAJ_BANK_SELECT 0xEF /*Bank0=0x00,Bank1=0x01*/
|
||||
//Register Bank 0
|
||||
#define PAJ_SUSPEND 0x03 /*I2C suspend command (Write 0x01 to enter suspend state). I2C wake-up command is slave ID wake-up. Refer to topic ¡°I2C Bus Timing Characteristics and Protocol¡±*/
|
||||
#define PAJ_INT_FLAG1_MASK 0x41 /*Gesture detection interrupt flag mask*/
|
||||
#define PAJ_INT_FLAG2_MASK 0x42 /*Gesture/PS detection interrupt flag mask*/
|
||||
#define PAJ_INT_FLAG1 0x43 /*Gesture detection interrupt flag*/
|
||||
#define PAJ_INT_FLAG2 0x44 /*Gesture/PS detection interrupt flag*/
|
||||
#define PAJ_STATE 0x45 /*State indicator for gesture detection (Only functional at gesture detection mode)*/
|
||||
#define PAJ_PS_HIGH_THRESHOLD 0x69 /*PS hysteresis high threshold (Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_LOW_THRESHOLD 0x6A /*PS hysteresis low threshold (Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_APPROACH_STATE 0x6B /*PS approach state, Approach = 1 , (8 bits PS data >= PS high threshold), Not Approach = 0 , (8 bits PS data <= PS low threshold)(Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_DATA 0x6C /*PS 8 bit data(Only functional at gesture detection mode)*/
|
||||
#define PAJ_OBJ_BRIGHTNESS 0xB0 /*Object Brightness (Max. 255)*/
|
||||
#define PAJ_OBJ_SIZE_L 0xB1 /*Object Size(Low 8 bit)*/
|
||||
#define PAJ_OBJ_SIZE_H 0xB2 /*Object Size(High 8 bit)*/
|
||||
|
||||
//Register Bank 1
|
||||
#define PAJ_PS_GAIN 0x44 /*PS gain setting (Only functional at proximity detection mode)*/
|
||||
#define PAJ_IDLE_S1_STEP_L 0x67 /*IDLE S1 Step, for setting the S1, Response Factor(Low 8 bit)*/
|
||||
#define PAJ_IDLE_S1_STEP_H 0x68 /*IDLE S1 Step, for setting the S1, Response Factor(High 8 bit)*/
|
||||
#define PAJ_IDLE_S2_STEP_L 0x69 /*IDLE S2 Step, for setting the S2, Response Factor(Low 8 bit)*/
|
||||
#define PAJ_IDLE_S2_STEP_H 0x6A /*IDLE S2 Step, for setting the S2, Response Factor(High 8 bit)*/
|
||||
#define PAJ_OPTOS1_TIME_L 0x6B /*OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 state(Low 8 bit)*/
|
||||
#define PAJ_OPTOS2_TIME_H 0x6C /*OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 stateHigh 8 bit)*/
|
||||
#define PAJ_S1TOS2_TIME_L 0x6D /*S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 state(Low 8 bit)*/
|
||||
#define PAJ_S1TOS2_TIME_H 0x6E /*S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 stateHigh 8 bit)*/
|
||||
#define PAJ_EN 0x72 /*Enable/Disable PAJ7620U2*/
|
||||
//Gesture detection interrupt flag
|
||||
#define PAJ_UP 0x01
|
||||
#define PAJ_DOWN 0x02
|
||||
#define PAJ_LEFT 0x04
|
||||
#define PAJ_RIGHT 0x08
|
||||
#define PAJ_FORWARD 0x10
|
||||
#define PAJ_BACKWARD 0x20
|
||||
#define PAJ_CLOCKWISE 0x40
|
||||
#define PAJ_COUNT_CLOCKWISE 0x80
|
||||
#define PAJ_WAVE 0x100
|
||||
//Initialize array size
|
||||
#define Init_Array sizeof(Init_Register_Array)/2
|
||||
#define PS_Array_SIZE sizeof(Init_PS_Array)/2
|
||||
#define Gesture_Array_SIZE sizeof(Init_Gesture_Array)/2
|
||||
//Power up initialize array
|
||||
unsigned char Init_Register_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x37,0x07},
|
||||
{0x38,0x17},
|
||||
{0x39,0x06},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0x46,0x2D},
|
||||
{0x47,0x0F},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x4A,0x1E},
|
||||
{0x4C,0x20},
|
||||
{0x51,0x10},
|
||||
{0x5E,0x10},
|
||||
{0x60,0x27},
|
||||
{0x80,0x42},
|
||||
{0x81,0x44},
|
||||
{0x82,0x04},
|
||||
{0x8B,0x01},
|
||||
{0x90,0x06},
|
||||
{0x95,0x0A},
|
||||
{0x96,0x0C},
|
||||
{0x97,0x05},
|
||||
{0x9A,0x14},
|
||||
{0x9C,0x3F},
|
||||
{0xA5,0x19},
|
||||
{0xCC,0x19},
|
||||
{0xCD,0x0B},
|
||||
{0xCE,0x13},
|
||||
{0xCF,0x64},
|
||||
{0xD0,0x21},
|
||||
{0xEF,0x01},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x25,0x01},
|
||||
{0x27,0x39},
|
||||
{0x28,0x7F},
|
||||
{0x29,0x08},
|
||||
{0x3E,0xFF},
|
||||
{0x5E,0x3D},
|
||||
{0x65,0x96},
|
||||
{0x67,0x97},
|
||||
{0x69,0xCD},
|
||||
{0x6A,0x01},
|
||||
{0x6D,0x2C},
|
||||
{0x6E,0x01},
|
||||
{0x72,0x01},
|
||||
{0x73,0x35},
|
||||
{0x74,0x00},
|
||||
{0x77,0x01},
|
||||
};
|
||||
//Approaches register initialization array
|
||||
unsigned char Init_PS_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x51,0x13},
|
||||
{0x83,0x20},
|
||||
{0x84,0x20},
|
||||
{0x85,0x00},
|
||||
{0x86,0x10},
|
||||
{0x87,0x00},
|
||||
{0x88,0x05},
|
||||
{0x89,0x18},
|
||||
{0x8A,0x10},
|
||||
{0x9f,0xf8},
|
||||
{0x69,0x96},
|
||||
{0x6A,0x02},
|
||||
{0xEF,0x01},
|
||||
{0x01,0x1E},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x41,0x50},
|
||||
{0x43,0x34},
|
||||
{0x65,0xCE},
|
||||
{0x66,0x0B},
|
||||
{0x67,0xCE},
|
||||
{0x68,0x0B},
|
||||
{0x69,0xE9},
|
||||
{0x6A,0x05},
|
||||
{0x6B,0x50},
|
||||
{0x6C,0xC3},
|
||||
{0x6D,0x50},
|
||||
{0x6E,0xC3},
|
||||
{0x74,0x05},
|
||||
};
|
||||
|
||||
//Gesture register initializes array
|
||||
const unsigned char Init_Gesture_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0xEF,0x00},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x51,0x10},
|
||||
{0x83,0x20},
|
||||
{0x9F,0xF9},
|
||||
{0xEF,0x01},
|
||||
{0x01,0x1E},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x41,0x40},
|
||||
{0x43,0x30},
|
||||
{0x65,0x96},
|
||||
{0x66,0x00},
|
||||
{0x67,0x97},
|
||||
{0x68,0x01},
|
||||
{0x69,0xCD},
|
||||
{0x6A,0x01},
|
||||
{0x6B,0xB0},
|
||||
{0x6C,0x04},
|
||||
{0x6D,0x2C},
|
||||
{0x6E,0x01},
|
||||
{0x74,0x00},
|
||||
{0xEF,0x00},
|
||||
{0x41,0xFF},
|
||||
{0x42,0x01},
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,231 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding:utf-8 -*-
|
||||
import time
|
||||
import smbus
|
||||
|
||||
#i2c address
|
||||
PAJ7620U2_I2C_ADDRESS = 0x73
|
||||
#Register Bank select
|
||||
PAJ_BANK_SELECT = 0xEF #Bank0== 0x00,Bank1== 0x01
|
||||
#Register Bank 0
|
||||
PAJ_SUSPEND = 0x03 #I2C suspend command (Write = 0x01 to enter suspend state). I2C wake-up command is slave ID wake-up. Refer to topic “I2C Bus Timing Characteristics and Protocol”
|
||||
PAJ_INT_FLAG1_MASK = 0x41 #Gesture detection interrupt flag mask
|
||||
PAJ_INT_FLAG2_MASK = 0x42 #Gesture/PS detection interrupt flag mask
|
||||
PAJ_INT_FLAG1 = 0x43 #Gesture detection interrupt flag
|
||||
PAJ_INT_FLAG2 = 0x44 #Gesture/PS detection interrupt flag
|
||||
PAJ_STATE = 0x45 #State indicator for gesture detection (Only functional at gesture detection mode)
|
||||
PAJ_PS_HIGH_THRESHOLD = 0x69 #PS hysteresis high threshold (Only functional at proximity detection mode)
|
||||
PAJ_PS_LOW_THRESHOLD = 0x6A #PS hysteresis low threshold (Only functional at proximity detection mode)
|
||||
PAJ_PS_APPROACH_STATE = 0x6B #PS approach state, Approach = 1 , (8 bits PS data >= PS high threshold), Not Approach = 0 , (8 bits PS data <= PS low threshold)(Only functional at proximity detection mode)
|
||||
PAJ_PS_DATA = 0x6C #PS 8 bit data(Only functional at gesture detection mode)
|
||||
PAJ_OBJ_BRIGHTNESS = 0xB0 #Object Brightness (Max. 255)
|
||||
PAJ_OBJ_SIZE_L = 0xB1 #Object Size(Low 8 bit)
|
||||
PAJ_OBJ_SIZE_H = 0xB2 #Object Size(High 8 bit)
|
||||
#Register Bank 1
|
||||
PAJ_PS_GAIN = 0x44 #PS gain setting (Only functional at proximity detection mode)
|
||||
PAJ_IDLE_S1_STEP_L = 0x67 #IDLE S1 Step, for setting the S1, Response Factor(Low 8 bit)
|
||||
PAJ_IDLE_S1_STEP_H = 0x68 #IDLE S1 Step, for setting the S1, Response Factor(High 8 bit)
|
||||
PAJ_IDLE_S2_STEP_L = 0x69 #IDLE S2 Step, for setting the S2, Response Factor(Low 8 bit)
|
||||
PAJ_IDLE_S2_STEP_H = 0x6A #IDLE S2 Step, for setting the S2, Response Factor(High 8 bit)
|
||||
PAJ_OPTOS1_TIME_L = 0x6B #OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 state(Low 8 bit)
|
||||
PAJ_OPTOS2_TIME_H = 0x6C #OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 stateHigh 8 bit)
|
||||
PAJ_S1TOS2_TIME_L = 0x6D #S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 state(Low 8 bit)
|
||||
PAJ_S1TOS2_TIME_H = 0x6E #S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 stateHigh 8 bit)
|
||||
PAJ_EN = 0x72 #Enable/Disable PAJ7620U2
|
||||
#Gesture detection interrupt flag
|
||||
PAJ_UP = 0x01
|
||||
PAJ_DOWN = 0x02
|
||||
PAJ_LEFT = 0x04
|
||||
PAJ_RIGHT = 0x08
|
||||
PAJ_FORWARD = 0x10
|
||||
PAJ_BACKWARD = 0x20
|
||||
PAJ_CLOCKWISE = 0x40
|
||||
PAJ_COUNT_CLOCKWISE = 0x80
|
||||
PAJ_WAVE = 0x100
|
||||
#Power up initialize array
|
||||
Init_Register_Array = (
|
||||
(0xEF,0x00),
|
||||
(0x37,0x07),
|
||||
(0x38,0x17),
|
||||
(0x39,0x06),
|
||||
(0x41,0x00),
|
||||
(0x42,0x00),
|
||||
(0x46,0x2D),
|
||||
(0x47,0x0F),
|
||||
(0x48,0x3C),
|
||||
(0x49,0x00),
|
||||
(0x4A,0x1E),
|
||||
(0x4C,0x20),
|
||||
(0x51,0x10),
|
||||
(0x5E,0x10),
|
||||
(0x60,0x27),
|
||||
(0x80,0x42),
|
||||
(0x81,0x44),
|
||||
(0x82,0x04),
|
||||
(0x8B,0x01),
|
||||
(0x90,0x06),
|
||||
(0x95,0x0A),
|
||||
(0x96,0x0C),
|
||||
(0x97,0x05),
|
||||
(0x9A,0x14),
|
||||
(0x9C,0x3F),
|
||||
(0xA5,0x19),
|
||||
(0xCC,0x19),
|
||||
(0xCD,0x0B),
|
||||
(0xCE,0x13),
|
||||
(0xCF,0x64),
|
||||
(0xD0,0x21),
|
||||
(0xEF,0x01),
|
||||
(0x02,0x0F),
|
||||
(0x03,0x10),
|
||||
(0x04,0x02),
|
||||
(0x25,0x01),
|
||||
(0x27,0x39),
|
||||
(0x28,0x7F),
|
||||
(0x29,0x08),
|
||||
(0x3E,0xFF),
|
||||
(0x5E,0x3D),
|
||||
(0x65,0x96),
|
||||
(0x67,0x97),
|
||||
(0x69,0xCD),
|
||||
(0x6A,0x01),
|
||||
(0x6D,0x2C),
|
||||
(0x6E,0x01),
|
||||
(0x72,0x01),
|
||||
(0x73,0x35),
|
||||
(0x74,0x00),
|
||||
(0x77,0x01),
|
||||
)
|
||||
#Approaches register initialization array
|
||||
Init_PS_Array = (
|
||||
(0xEF,0x00),
|
||||
(0x41,0x00),
|
||||
(0x42,0x00),
|
||||
(0x48,0x3C),
|
||||
(0x49,0x00),
|
||||
(0x51,0x13),
|
||||
(0x83,0x20),
|
||||
(0x84,0x20),
|
||||
(0x85,0x00),
|
||||
(0x86,0x10),
|
||||
(0x87,0x00),
|
||||
(0x88,0x05),
|
||||
(0x89,0x18),
|
||||
(0x8A,0x10),
|
||||
(0x9f,0xf8),
|
||||
(0x69,0x96),
|
||||
(0x6A,0x02),
|
||||
(0xEF,0x01),
|
||||
(0x01,0x1E),
|
||||
(0x02,0x0F),
|
||||
(0x03,0x10),
|
||||
(0x04,0x02),
|
||||
(0x41,0x50),
|
||||
(0x43,0x34),
|
||||
(0x65,0xCE),
|
||||
(0x66,0x0B),
|
||||
(0x67,0xCE),
|
||||
(0x68,0x0B),
|
||||
(0x69,0xE9),
|
||||
(0x6A,0x05),
|
||||
(0x6B,0x50),
|
||||
(0x6C,0xC3),
|
||||
(0x6D,0x50),
|
||||
(0x6E,0xC3),
|
||||
(0x74,0x05),
|
||||
)
|
||||
#Gesture register initializes array
|
||||
Init_Gesture_Array = (
|
||||
(0xEF,0x00),
|
||||
(0x41,0x00),
|
||||
(0x42,0x00),
|
||||
(0xEF,0x00),
|
||||
(0x48,0x3C),
|
||||
(0x49,0x00),
|
||||
(0x51,0x10),
|
||||
(0x83,0x20),
|
||||
(0x9F,0xF9),
|
||||
(0xEF,0x01),
|
||||
(0x01,0x1E),
|
||||
(0x02,0x0F),
|
||||
(0x03,0x10),
|
||||
(0x04,0x02),
|
||||
(0x41,0x40),
|
||||
(0x43,0x30),
|
||||
(0x65,0x96),
|
||||
(0x66,0x00),
|
||||
(0x67,0x97),
|
||||
(0x68,0x01),
|
||||
(0x69,0xCD),
|
||||
(0x6A,0x01),
|
||||
(0x6B,0xB0),
|
||||
(0x6C,0x04),
|
||||
(0x6D,0x2C),
|
||||
(0x6E,0x01),
|
||||
(0x74,0x00),
|
||||
(0xEF,0x00),
|
||||
(0x41,0xFF),
|
||||
(0x42,0x01),
|
||||
)
|
||||
class PAJ7620U2(object):
|
||||
def __init__(self,address=PAJ7620U2_I2C_ADDRESS):
|
||||
self._address = address
|
||||
self._bus = smbus.SMBus(1)
|
||||
time.sleep(0.5)
|
||||
if self._read_byte(0x00) == 0x20:
|
||||
print("\nGesture Sensor OK\n")
|
||||
for num in range(len(Init_Register_Array)):
|
||||
self._write_byte(Init_Register_Array[num][0],Init_Register_Array[num][1])
|
||||
else:
|
||||
print("\nGesture Sensor Error\n")
|
||||
self._write_byte(PAJ_BANK_SELECT, 0)
|
||||
for num in range(len(Init_Gesture_Array)):
|
||||
self._write_byte(Init_Gesture_Array[num][0],Init_Gesture_Array[num][1])
|
||||
def _read_byte(self,cmd):
|
||||
return self._bus.read_byte_data(self._address,cmd)
|
||||
|
||||
def _read_u16(self,cmd):
|
||||
LSB = self._bus.read_byte_data(self._address,cmd)
|
||||
MSB = self._bus.read_byte_data(self._address,cmd+1)
|
||||
return (MSB << 8) + LSB
|
||||
def _write_byte(self,cmd,val):
|
||||
self._bus.write_byte_data(self._address,cmd,val)
|
||||
def check_gesture(self):
|
||||
Gesture_Data=self._read_u16(PAJ_INT_FLAG1)
|
||||
if Gesture_Data == PAJ_UP:
|
||||
print("Up\r\n")
|
||||
elif Gesture_Data == PAJ_DOWN:
|
||||
print("Down\r\n")
|
||||
elif Gesture_Data == PAJ_LEFT:
|
||||
print("Left\r\n")
|
||||
elif Gesture_Data == PAJ_RIGHT:
|
||||
print("Right\r\n")
|
||||
elif Gesture_Data == PAJ_FORWARD:
|
||||
print("Forward\r\n")
|
||||
elif Gesture_Data == PAJ_BACKWARD:
|
||||
print("Backward\r\n")
|
||||
elif Gesture_Data == PAJ_CLOCKWISE:
|
||||
print("Clockwise\r\n")
|
||||
elif Gesture_Data == PAJ_COUNT_CLOCKWISE:
|
||||
print("AntiClockwise\r\n")
|
||||
elif Gesture_Data == PAJ_WAVE:
|
||||
print("Wave\r\n")
|
||||
return Gesture_Data
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
import time
|
||||
|
||||
print("\nGesture Sensor Test Program ...\n")
|
||||
|
||||
paj7620u2=PAJ7620U2()
|
||||
|
||||
while True:
|
||||
time.sleep(0.05)
|
||||
paj7620u2.check_gesture()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding:utf-8 -*-
|
||||
import time
|
||||
import smbus
|
||||
|
||||
#i2c address
|
||||
PAJ7620U2_I2C_ADDRESS = 0x73
|
||||
#Register Bank select
|
||||
PAJ_BANK_SELECT = 0xEF #Bank0== 0x00,Bank1== 0x01
|
||||
#Register Bank 0
|
||||
PAJ_SUSPEND = 0x03 #I2C suspend command (Write = 0x01 to enter suspend state). I2C wake-up command is slave ID wake-up. Refer to topic “I2C Bus Timing Characteristics and Protocol”
|
||||
PAJ_INT_FLAG1_MASK = 0x41 #Gesture detection interrupt flag mask
|
||||
PAJ_INT_FLAG2_MASK = 0x42 #Gesture/PS detection interrupt flag mask
|
||||
PAJ_INT_FLAG1 = 0x43 #Gesture detection interrupt flag
|
||||
PAJ_INT_FLAG2 = 0x44 #Gesture/PS detection interrupt flag
|
||||
PAJ_STATE = 0x45 #State indicator for gesture detection (Only functional at gesture detection mode)
|
||||
PAJ_PS_HIGH_THRESHOLD = 0x69 #PS hysteresis high threshold (Only functional at proximity detection mode)
|
||||
PAJ_PS_LOW_THRESHOLD = 0x6A #PS hysteresis low threshold (Only functional at proximity detection mode)
|
||||
PAJ_PS_APPROACH_STATE = 0x6B #PS approach state, Approach = 1 , (8 bits PS data >= PS high threshold), Not Approach = 0 , (8 bits PS data <= PS low threshold)(Only functional at proximity detection mode)
|
||||
PAJ_PS_DATA = 0x6C #PS 8 bit data(Only functional at gesture detection mode)
|
||||
PAJ_OBJ_BRIGHTNESS = 0xB0 #Object Brightness (Max. 255)
|
||||
PAJ_OBJ_SIZE_L = 0xB1 #Object Size(Low 8 bit)
|
||||
PAJ_OBJ_SIZE_H = 0xB2 #Object Size(High 8 bit)
|
||||
#Register Bank 1
|
||||
PAJ_PS_GAIN = 0x44 #PS gain setting (Only functional at proximity detection mode)
|
||||
PAJ_IDLE_S1_STEP_L = 0x67 #IDLE S1 Step, for setting the S1, Response Factor(Low 8 bit)
|
||||
PAJ_IDLE_S1_STEP_H = 0x68 #IDLE S1 Step, for setting the S1, Response Factor(High 8 bit)
|
||||
PAJ_IDLE_S2_STEP_L = 0x69 #IDLE S2 Step, for setting the S2, Response Factor(Low 8 bit)
|
||||
PAJ_IDLE_S2_STEP_H = 0x6A #IDLE S2 Step, for setting the S2, Response Factor(High 8 bit)
|
||||
PAJ_OPTOS1_TIME_L = 0x6B #OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 state(Low 8 bit)
|
||||
PAJ_OPTOS2_TIME_H = 0x6C #OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 stateHigh 8 bit)
|
||||
PAJ_S1TOS2_TIME_L = 0x6D #S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 state(Low 8 bit)
|
||||
PAJ_S1TOS2_TIME_H = 0x6E #S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 stateHigh 8 bit)
|
||||
PAJ_EN = 0x72 #Enable/Disable PAJ7620U2
|
||||
#Gesture detection interrupt flag
|
||||
PAJ_UP = 0x01
|
||||
PAJ_DOWN = 0x02
|
||||
PAJ_LEFT = 0x04
|
||||
PAJ_RIGHT = 0x08
|
||||
PAJ_FORWARD = 0x10
|
||||
PAJ_BACKWARD = 0x20
|
||||
PAJ_CLOCKWISE = 0x40
|
||||
PAJ_COUNT_CLOCKWISE = 0x80
|
||||
PAJ_WAVE = 0x100
|
||||
#Power up initialize array
|
||||
Init_Register_Array = (
|
||||
(0xEF,0x00),
|
||||
(0x37,0x07),
|
||||
(0x38,0x17),
|
||||
(0x39,0x06),
|
||||
(0x41,0x00),
|
||||
(0x42,0x00),
|
||||
(0x46,0x2D),
|
||||
(0x47,0x0F),
|
||||
(0x48,0x3C),
|
||||
(0x49,0x00),
|
||||
(0x4A,0x1E),
|
||||
(0x4C,0x20),
|
||||
(0x51,0x10),
|
||||
(0x5E,0x10),
|
||||
(0x60,0x27),
|
||||
(0x80,0x42),
|
||||
(0x81,0x44),
|
||||
(0x82,0x04),
|
||||
(0x8B,0x01),
|
||||
(0x90,0x06),
|
||||
(0x95,0x0A),
|
||||
(0x96,0x0C),
|
||||
(0x97,0x05),
|
||||
(0x9A,0x14),
|
||||
(0x9C,0x3F),
|
||||
(0xA5,0x19),
|
||||
(0xCC,0x19),
|
||||
(0xCD,0x0B),
|
||||
(0xCE,0x13),
|
||||
(0xCF,0x64),
|
||||
(0xD0,0x21),
|
||||
(0xEF,0x01),
|
||||
(0x02,0x0F),
|
||||
(0x03,0x10),
|
||||
(0x04,0x02),
|
||||
(0x25,0x01),
|
||||
(0x27,0x39),
|
||||
(0x28,0x7F),
|
||||
(0x29,0x08),
|
||||
(0x3E,0xFF),
|
||||
(0x5E,0x3D),
|
||||
(0x65,0x96),
|
||||
(0x67,0x97),
|
||||
(0x69,0xCD),
|
||||
(0x6A,0x01),
|
||||
(0x6D,0x2C),
|
||||
(0x6E,0x01),
|
||||
(0x72,0x01),
|
||||
(0x73,0x35),
|
||||
(0x74,0x00),
|
||||
(0x77,0x01),
|
||||
)
|
||||
#Approaches register initialization array
|
||||
Init_PS_Array = (
|
||||
(0xEF,0x00),
|
||||
(0x41,0x00),
|
||||
(0x42,0x00),
|
||||
(0x48,0x3C),
|
||||
(0x49,0x00),
|
||||
(0x51,0x13),
|
||||
(0x83,0x20),
|
||||
(0x84,0x20),
|
||||
(0x85,0x00),
|
||||
(0x86,0x10),
|
||||
(0x87,0x00),
|
||||
(0x88,0x05),
|
||||
(0x89,0x18),
|
||||
(0x8A,0x10),
|
||||
(0x9f,0xf8),
|
||||
(0x69,0x96),
|
||||
(0x6A,0x02),
|
||||
(0xEF,0x01),
|
||||
(0x01,0x1E),
|
||||
(0x02,0x0F),
|
||||
(0x03,0x10),
|
||||
(0x04,0x02),
|
||||
(0x41,0x50),
|
||||
(0x43,0x34),
|
||||
(0x65,0xCE),
|
||||
(0x66,0x0B),
|
||||
(0x67,0xCE),
|
||||
(0x68,0x0B),
|
||||
(0x69,0xE9),
|
||||
(0x6A,0x05),
|
||||
(0x6B,0x50),
|
||||
(0x6C,0xC3),
|
||||
(0x6D,0x50),
|
||||
(0x6E,0xC3),
|
||||
(0x74,0x05),
|
||||
)
|
||||
#Gesture register initializes array
|
||||
Init_Gesture_Array = (
|
||||
(0xEF,0x00),
|
||||
(0x41,0x00),
|
||||
(0x42,0x00),
|
||||
(0xEF,0x00),
|
||||
(0x48,0x3C),
|
||||
(0x49,0x00),
|
||||
(0x51,0x10),
|
||||
(0x83,0x20),
|
||||
(0x9F,0xF9),
|
||||
(0xEF,0x01),
|
||||
(0x01,0x1E),
|
||||
(0x02,0x0F),
|
||||
(0x03,0x10),
|
||||
(0x04,0x02),
|
||||
(0x41,0x40),
|
||||
(0x43,0x30),
|
||||
(0x65,0x96),
|
||||
(0x66,0x00),
|
||||
(0x67,0x97),
|
||||
(0x68,0x01),
|
||||
(0x69,0xCD),
|
||||
(0x6A,0x01),
|
||||
(0x6B,0xB0),
|
||||
(0x6C,0x04),
|
||||
(0x6D,0x2C),
|
||||
(0x6E,0x01),
|
||||
(0x74,0x00),
|
||||
(0xEF,0x00),
|
||||
(0x41,0xFF),
|
||||
(0x42,0x01),
|
||||
)
|
||||
class PAJ7620U2(object):
|
||||
def __init__(self,address=PAJ7620U2_I2C_ADDRESS):
|
||||
self._address = address
|
||||
self._bus = smbus.SMBus(1)
|
||||
time.sleep(0.5)
|
||||
if self._read_byte(0x00) == 0x20:
|
||||
print("\nGesture Sensor OK\n")
|
||||
for num in range(len(Init_Register_Array)):
|
||||
self._write_byte(Init_Register_Array[num][0],Init_Register_Array[num][1])
|
||||
else:
|
||||
print("\nGesture Sensor Error\n")
|
||||
self._write_byte(PAJ_BANK_SELECT, 0)
|
||||
for num in range(len(Init_PS_Array)):
|
||||
self._write_byte(Init_PS_Array[num][0],Init_PS_Array[num][1])
|
||||
self._write_byte(PAJ_BANK_SELECT, 0)
|
||||
def _read_byte(self,cmd):
|
||||
return self._bus.read_byte_data(self._address,cmd)
|
||||
|
||||
def _read_u16(self,cmd):
|
||||
LSB = self._bus.read_byte_data(self._address,cmd)
|
||||
MSB = self._bus.read_byte_data(self._address,cmd+1)
|
||||
return (MSB << 8) + LSB
|
||||
def _write_byte(self,cmd,val):
|
||||
self._bus.write_byte_data(self._address,cmd,val)
|
||||
def check_gesture(self):
|
||||
OBJ_BRIGHTNESS = self._read_byte(PAJ_OBJ_BRIGHTNESS)
|
||||
OBJ_SIZE = self._read_u16(PAJ_OBJ_SIZE_L)
|
||||
print(' Object brightness = %.f , Object size = %.f'%(OBJ_BRIGHTNESS,OBJ_SIZE))
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
import time
|
||||
|
||||
print("\nGesture Sensor Test Program ...\n")
|
||||
|
||||
paj7620u2=PAJ7620U2()
|
||||
|
||||
while True:
|
||||
time.sleep(0.1)
|
||||
paj7620u2.check_gesture()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
PAJ7620U2:PAJ7620U2.c PAJ7620U2.h
|
||||
gcc -Wall PAJ7620U2.c -o PAJ7620U2 -lwiringPi -lm
|
||||
clean:
|
||||
rm PAJ7620U2
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#include <wiringPi.h>
|
||||
#include <wiringPiI2C.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "PAJ7620U2.h"
|
||||
int fd;
|
||||
/******************* PAJ7620U2 Driver Interface *****************************/
|
||||
char I2C_readByte(int reg)
|
||||
{
|
||||
return wiringPiI2CReadReg8(fd, reg);
|
||||
}
|
||||
|
||||
unsigned short I2C_readU16(int reg)
|
||||
{
|
||||
return wiringPiI2CReadReg16(fd, reg);
|
||||
}
|
||||
void I2C_writeByte(int reg, int val)
|
||||
{
|
||||
wiringPiI2CWriteReg8(fd, reg, val);
|
||||
}
|
||||
unsigned char PAJ7620U2_init()
|
||||
{
|
||||
unsigned char i,State;
|
||||
fd=wiringPiI2CSetup(PAJ7620U2_I2C_ADDRESS);
|
||||
delay(5);
|
||||
State = I2C_readByte(0x00); //Read State
|
||||
if (State != 0x20) return 0; //Wake up failed
|
||||
I2C_writeByte(PAJ_BANK_SELECT, 0); //Select Bank 0
|
||||
for (i=0;i< Init_Array;i++)
|
||||
{
|
||||
I2C_writeByte(Init_Register_Array[i][0], Init_Register_Array[i][1]);//Power up initialize
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
unsigned char i;
|
||||
unsigned short Gesture_Data;
|
||||
printf("\nGesture Sensor Test Program ...\n");
|
||||
if (wiringPiSetup() < 0) return 1;
|
||||
delay(5);
|
||||
if(!PAJ7620U2_init())
|
||||
{ printf("\nGesture Sensor Error\n");
|
||||
return 0;
|
||||
}
|
||||
printf("\nGesture Sensor OK\n");
|
||||
I2C_writeByte(PAJ_BANK_SELECT, 0);//Select Bank 0
|
||||
for (i = 0; i < Gesture_Array_SIZE; i++)
|
||||
{
|
||||
I2C_writeByte(Init_Gesture_Array[i][0], Init_Gesture_Array[i][1]);//Gesture register initializes
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
Gesture_Data = I2C_readU16(PAJ_INT_FLAG1);
|
||||
|
||||
if (Gesture_Data)
|
||||
{
|
||||
switch (Gesture_Data)
|
||||
{
|
||||
case PAJ_UP: printf("Up\r\n"); break;
|
||||
case PAJ_DOWN: printf("Down\r\n"); break;
|
||||
case PAJ_LEFT: printf("Left\r\n"); break;
|
||||
case PAJ_RIGHT: printf("Right\r\n"); break;
|
||||
case PAJ_FORWARD: printf("Forward\r\n"); break;
|
||||
case PAJ_BACKWARD: printf("Backward\r\n"); break;
|
||||
case PAJ_CLOCKWISE: printf("Clockwise\r\n"); break;
|
||||
case PAJ_COUNT_CLOCKWISE: printf("AntiClockwise\r\n"); break;
|
||||
case PAJ_WAVE: printf("Wave\r\n"); break;
|
||||
default: break;
|
||||
}
|
||||
Gesture_Data=0;
|
||||
delay(50);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
#ifndef _PAJ7620U2_
|
||||
#define _PAJ7620U2_
|
||||
|
||||
//i2c address
|
||||
#define PAJ7620U2_I2C_ADDRESS 0x73
|
||||
//Register Bank select
|
||||
#define PAJ_BANK_SELECT 0xEF /*Bank0=0x00,Bank1=0x01*/
|
||||
//Register Bank 0
|
||||
#define PAJ_SUSPEND 0x03 /*I2C suspend command (Write 0x01 to enter suspend state). I2C wake-up command is slave ID wake-up. Refer to topic ¡°I2C Bus Timing Characteristics and Protocol¡±*/
|
||||
#define PAJ_INT_FLAG1_MASK 0x41 /*Gesture detection interrupt flag mask*/
|
||||
#define PAJ_INT_FLAG2_MASK 0x42 /*Gesture/PS detection interrupt flag mask*/
|
||||
#define PAJ_INT_FLAG1 0x43 /*Gesture detection interrupt flag*/
|
||||
#define PAJ_INT_FLAG2 0x44 /*Gesture/PS detection interrupt flag*/
|
||||
#define PAJ_STATE 0x45 /*State indicator for gesture detection (Only functional at gesture detection mode)*/
|
||||
#define PAJ_PS_HIGH_THRESHOLD 0x69 /*PS hysteresis high threshold (Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_LOW_THRESHOLD 0x6A /*PS hysteresis low threshold (Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_APPROACH_STATE 0x6B /*PS approach state, Approach = 1 , (8 bits PS data >= PS high threshold), Not Approach = 0 , (8 bits PS data <= PS low threshold)(Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_DATA 0x6C /*PS 8 bit data(Only functional at gesture detection mode)*/
|
||||
#define PAJ_OBJ_BRIGHTNESS 0xB0 /*Object Brightness (Max. 255)*/
|
||||
#define PAJ_OBJ_SIZE_L 0xB1 /*Object Size(Low 8 bit)*/
|
||||
#define PAJ_OBJ_SIZE_H 0xB2 /*Object Size(High 8 bit)*/
|
||||
|
||||
//Register Bank 1
|
||||
#define PAJ_PS_GAIN 0x44 /*PS gain setting (Only functional at proximity detection mode)*/
|
||||
#define PAJ_IDLE_S1_STEP_L 0x67 /*IDLE S1 Step, for setting the S1, Response Factor(Low 8 bit)*/
|
||||
#define PAJ_IDLE_S1_STEP_H 0x68 /*IDLE S1 Step, for setting the S1, Response Factor(High 8 bit)*/
|
||||
#define PAJ_IDLE_S2_STEP_L 0x69 /*IDLE S2 Step, for setting the S2, Response Factor(Low 8 bit)*/
|
||||
#define PAJ_IDLE_S2_STEP_H 0x6A /*IDLE S2 Step, for setting the S2, Response Factor(High 8 bit)*/
|
||||
#define PAJ_OPTOS1_TIME_L 0x6B /*OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 state(Low 8 bit)*/
|
||||
#define PAJ_OPTOS2_TIME_H 0x6C /*OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 stateHigh 8 bit)*/
|
||||
#define PAJ_S1TOS2_TIME_L 0x6D /*S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 state(Low 8 bit)*/
|
||||
#define PAJ_S1TOS2_TIME_H 0x6E /*S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 stateHigh 8 bit)*/
|
||||
#define PAJ_EN 0x72 /*Enable/Disable PAJ7620U2*/
|
||||
//Gesture detection interrupt flag
|
||||
#define PAJ_UP 0x01
|
||||
#define PAJ_DOWN 0x02
|
||||
#define PAJ_LEFT 0x04
|
||||
#define PAJ_RIGHT 0x08
|
||||
#define PAJ_FORWARD 0x10
|
||||
#define PAJ_BACKWARD 0x20
|
||||
#define PAJ_CLOCKWISE 0x40
|
||||
#define PAJ_COUNT_CLOCKWISE 0x80
|
||||
#define PAJ_WAVE 0x100
|
||||
//Initialize array size
|
||||
#define Init_Array sizeof(Init_Register_Array)/2
|
||||
#define PS_Array_SIZE sizeof(Init_PS_Array)/2
|
||||
#define Gesture_Array_SIZE sizeof(Init_Gesture_Array)/2
|
||||
//Power up initialize array
|
||||
unsigned char Init_Register_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x37,0x07},
|
||||
{0x38,0x17},
|
||||
{0x39,0x06},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0x46,0x2D},
|
||||
{0x47,0x0F},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x4A,0x1E},
|
||||
{0x4C,0x20},
|
||||
{0x51,0x10},
|
||||
{0x5E,0x10},
|
||||
{0x60,0x27},
|
||||
{0x80,0x42},
|
||||
{0x81,0x44},
|
||||
{0x82,0x04},
|
||||
{0x8B,0x01},
|
||||
{0x90,0x06},
|
||||
{0x95,0x0A},
|
||||
{0x96,0x0C},
|
||||
{0x97,0x05},
|
||||
{0x9A,0x14},
|
||||
{0x9C,0x3F},
|
||||
{0xA5,0x19},
|
||||
{0xCC,0x19},
|
||||
{0xCD,0x0B},
|
||||
{0xCE,0x13},
|
||||
{0xCF,0x64},
|
||||
{0xD0,0x21},
|
||||
{0xEF,0x01},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x25,0x01},
|
||||
{0x27,0x39},
|
||||
{0x28,0x7F},
|
||||
{0x29,0x08},
|
||||
{0x3E,0xFF},
|
||||
{0x5E,0x3D},
|
||||
{0x65,0x96},
|
||||
{0x67,0x97},
|
||||
{0x69,0xCD},
|
||||
{0x6A,0x01},
|
||||
{0x6D,0x2C},
|
||||
{0x6E,0x01},
|
||||
{0x72,0x01},
|
||||
{0x73,0x35},
|
||||
{0x74,0x00},
|
||||
{0x77,0x01},
|
||||
};
|
||||
//Approaches register initialization array
|
||||
unsigned char Init_PS_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x51,0x13},
|
||||
{0x83,0x20},
|
||||
{0x84,0x20},
|
||||
{0x85,0x00},
|
||||
{0x86,0x10},
|
||||
{0x87,0x00},
|
||||
{0x88,0x05},
|
||||
{0x89,0x18},
|
||||
{0x8A,0x10},
|
||||
{0x9f,0xf8},
|
||||
{0x69,0x96},
|
||||
{0x6A,0x02},
|
||||
{0xEF,0x01},
|
||||
{0x01,0x1E},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x41,0x50},
|
||||
{0x43,0x34},
|
||||
{0x65,0xCE},
|
||||
{0x66,0x0B},
|
||||
{0x67,0xCE},
|
||||
{0x68,0x0B},
|
||||
{0x69,0xE9},
|
||||
{0x6A,0x05},
|
||||
{0x6B,0x50},
|
||||
{0x6C,0xC3},
|
||||
{0x6D,0x50},
|
||||
{0x6E,0xC3},
|
||||
{0x74,0x05},
|
||||
};
|
||||
|
||||
//Gesture register initializes array
|
||||
const unsigned char Init_Gesture_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0xEF,0x00},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x51,0x10},
|
||||
{0x83,0x20},
|
||||
{0x9F,0xF9},
|
||||
{0xEF,0x01},
|
||||
{0x01,0x1E},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x41,0x40},
|
||||
{0x43,0x30},
|
||||
{0x65,0x96},
|
||||
{0x66,0x00},
|
||||
{0x67,0x97},
|
||||
{0x68,0x01},
|
||||
{0x69,0xCD},
|
||||
{0x6A,0x01},
|
||||
{0x6B,0xB0},
|
||||
{0x6C,0x04},
|
||||
{0x6D,0x2C},
|
||||
{0x6E,0x01},
|
||||
{0x74,0x00},
|
||||
{0xEF,0x00},
|
||||
{0x41,0xFF},
|
||||
{0x42,0x01},
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,5 @@
|
||||
PAJ7620U2:PAJ7620U2.c PAJ7620U2.h
|
||||
gcc -Wall PAJ7620U2.c -o PAJ7620U2 -lwiringPi -lm
|
||||
clean:
|
||||
rm PAJ7620U2
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
#include <wiringPi.h>
|
||||
#include <wiringPiI2C.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "PAJ7620U2.h"
|
||||
int fd;
|
||||
/******************* PAJ7620U2 Driver Interface *****************************/
|
||||
char I2C_readByte(int reg)
|
||||
{
|
||||
return wiringPiI2CReadReg8(fd, reg);
|
||||
}
|
||||
|
||||
unsigned short I2C_readU16(int reg)
|
||||
{
|
||||
return wiringPiI2CReadReg16(fd, reg);
|
||||
}
|
||||
void I2C_writeByte(int reg, int val)
|
||||
{
|
||||
wiringPiI2CWriteReg8(fd, reg, val);
|
||||
}
|
||||
unsigned char PAJ7620U2_init()
|
||||
{
|
||||
unsigned char i,State;
|
||||
fd=wiringPiI2CSetup(PAJ7620U2_I2C_ADDRESS);
|
||||
delay(5);
|
||||
State = I2C_readByte(0x00); //Read State
|
||||
if (State != 0x20) return 0; //Wake up failed
|
||||
I2C_writeByte(PAJ_BANK_SELECT, 0); //Select Bank 0
|
||||
for (i=0;i< Init_Array;i++)
|
||||
{
|
||||
I2C_writeByte(Init_Register_Array[i][0], Init_Register_Array[i][1]);//Power up initialize
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
unsigned char i, OBJ_BRIGHTNESS;
|
||||
unsigned short OBJ_SIZE;
|
||||
printf("\nGesture Sensor Test Program ...\n");
|
||||
if (wiringPiSetup() < 0) return 1;
|
||||
delay(5);
|
||||
if(!PAJ7620U2_init())
|
||||
{ printf("\nGesture Sensor Error\n");
|
||||
return 0;
|
||||
}
|
||||
printf("\nGesture Sensor OK\n");
|
||||
I2C_writeByte(PAJ_BANK_SELECT, 0);//Select Bank 0
|
||||
for (i = 0; i < PS_Array_SIZE; i++)
|
||||
{
|
||||
I2C_writeByte(Init_PS_Array[i][0], Init_PS_Array[i][1]);//Gesture register initializes
|
||||
}
|
||||
I2C_writeByte(PAJ_BANK_SELECT, 0);//Select Bank 0
|
||||
while (1)
|
||||
{
|
||||
OBJ_BRIGHTNESS = I2C_readByte(PAJ_OBJ_BRIGHTNESS);
|
||||
OBJ_SIZE = I2C_readU16(PAJ_OBJ_SIZE_L);
|
||||
printf("Object brightness = %d ,Object size = %d\n", OBJ_BRIGHTNESS, OBJ_SIZE);//Object Brightness (Max. 255),Object Size (Max. 900)
|
||||
delay(50);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
#ifndef _PAJ7620U2_
|
||||
#define _PAJ7620U2_
|
||||
|
||||
//i2c address
|
||||
#define PAJ7620U2_I2C_ADDRESS 0x73
|
||||
//Register Bank select
|
||||
#define PAJ_BANK_SELECT 0xEF /*Bank0=0x00,Bank1=0x01*/
|
||||
//Register Bank 0
|
||||
#define PAJ_SUSPEND 0x03 /*I2C suspend command (Write 0x01 to enter suspend state). I2C wake-up command is slave ID wake-up. Refer to topic ¡°I2C Bus Timing Characteristics and Protocol¡±*/
|
||||
#define PAJ_INT_FLAG1_MASK 0x41 /*Gesture detection interrupt flag mask*/
|
||||
#define PAJ_INT_FLAG2_MASK 0x42 /*Gesture/PS detection interrupt flag mask*/
|
||||
#define PAJ_INT_FLAG1 0x43 /*Gesture detection interrupt flag*/
|
||||
#define PAJ_INT_FLAG2 0x44 /*Gesture/PS detection interrupt flag*/
|
||||
#define PAJ_STATE 0x45 /*State indicator for gesture detection (Only functional at gesture detection mode)*/
|
||||
#define PAJ_PS_HIGH_THRESHOLD 0x69 /*PS hysteresis high threshold (Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_LOW_THRESHOLD 0x6A /*PS hysteresis low threshold (Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_APPROACH_STATE 0x6B /*PS approach state, Approach = 1 , (8 bits PS data >= PS high threshold), Not Approach = 0 , (8 bits PS data <= PS low threshold)(Only functional at proximity detection mode)*/
|
||||
#define PAJ_PS_DATA 0x6C /*PS 8 bit data(Only functional at gesture detection mode)*/
|
||||
#define PAJ_OBJ_BRIGHTNESS 0xB0 /*Object Brightness (Max. 255)*/
|
||||
#define PAJ_OBJ_SIZE_L 0xB1 /*Object Size(Low 8 bit)*/
|
||||
#define PAJ_OBJ_SIZE_H 0xB2 /*Object Size(High 8 bit)*/
|
||||
|
||||
//Register Bank 1
|
||||
#define PAJ_PS_GAIN 0x44 /*PS gain setting (Only functional at proximity detection mode)*/
|
||||
#define PAJ_IDLE_S1_STEP_L 0x67 /*IDLE S1 Step, for setting the S1, Response Factor(Low 8 bit)*/
|
||||
#define PAJ_IDLE_S1_STEP_H 0x68 /*IDLE S1 Step, for setting the S1, Response Factor(High 8 bit)*/
|
||||
#define PAJ_IDLE_S2_STEP_L 0x69 /*IDLE S2 Step, for setting the S2, Response Factor(Low 8 bit)*/
|
||||
#define PAJ_IDLE_S2_STEP_H 0x6A /*IDLE S2 Step, for setting the S2, Response Factor(High 8 bit)*/
|
||||
#define PAJ_OPTOS1_TIME_L 0x6B /*OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 state(Low 8 bit)*/
|
||||
#define PAJ_OPTOS2_TIME_H 0x6C /*OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 stateHigh 8 bit)*/
|
||||
#define PAJ_S1TOS2_TIME_L 0x6D /*S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 state(Low 8 bit)*/
|
||||
#define PAJ_S1TOS2_TIME_H 0x6E /*S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 stateHigh 8 bit)*/
|
||||
#define PAJ_EN 0x72 /*Enable/Disable PAJ7620U2*/
|
||||
//Gesture detection interrupt flag
|
||||
#define PAJ_UP 0x01
|
||||
#define PAJ_DOWN 0x02
|
||||
#define PAJ_LEFT 0x04
|
||||
#define PAJ_RIGHT 0x08
|
||||
#define PAJ_FORWARD 0x10
|
||||
#define PAJ_BACKWARD 0x20
|
||||
#define PAJ_CLOCKWISE 0x40
|
||||
#define PAJ_COUNT_CLOCKWISE 0x80
|
||||
#define PAJ_WAVE 0x100
|
||||
//Initialize array size
|
||||
#define Init_Array sizeof(Init_Register_Array)/2
|
||||
#define PS_Array_SIZE sizeof(Init_PS_Array)/2
|
||||
#define Gesture_Array_SIZE sizeof(Init_Gesture_Array)/2
|
||||
//Power up initialize array
|
||||
unsigned char Init_Register_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x37,0x07},
|
||||
{0x38,0x17},
|
||||
{0x39,0x06},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0x46,0x2D},
|
||||
{0x47,0x0F},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x4A,0x1E},
|
||||
{0x4C,0x20},
|
||||
{0x51,0x10},
|
||||
{0x5E,0x10},
|
||||
{0x60,0x27},
|
||||
{0x80,0x42},
|
||||
{0x81,0x44},
|
||||
{0x82,0x04},
|
||||
{0x8B,0x01},
|
||||
{0x90,0x06},
|
||||
{0x95,0x0A},
|
||||
{0x96,0x0C},
|
||||
{0x97,0x05},
|
||||
{0x9A,0x14},
|
||||
{0x9C,0x3F},
|
||||
{0xA5,0x19},
|
||||
{0xCC,0x19},
|
||||
{0xCD,0x0B},
|
||||
{0xCE,0x13},
|
||||
{0xCF,0x64},
|
||||
{0xD0,0x21},
|
||||
{0xEF,0x01},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x25,0x01},
|
||||
{0x27,0x39},
|
||||
{0x28,0x7F},
|
||||
{0x29,0x08},
|
||||
{0x3E,0xFF},
|
||||
{0x5E,0x3D},
|
||||
{0x65,0x96},
|
||||
{0x67,0x97},
|
||||
{0x69,0xCD},
|
||||
{0x6A,0x01},
|
||||
{0x6D,0x2C},
|
||||
{0x6E,0x01},
|
||||
{0x72,0x01},
|
||||
{0x73,0x35},
|
||||
{0x74,0x00},
|
||||
{0x77,0x01},
|
||||
};
|
||||
//Approaches register initialization array
|
||||
unsigned char Init_PS_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x51,0x13},
|
||||
{0x83,0x20},
|
||||
{0x84,0x20},
|
||||
{0x85,0x00},
|
||||
{0x86,0x10},
|
||||
{0x87,0x00},
|
||||
{0x88,0x05},
|
||||
{0x89,0x18},
|
||||
{0x8A,0x10},
|
||||
{0x9f,0xf8},
|
||||
{0x69,0x96},
|
||||
{0x6A,0x02},
|
||||
{0xEF,0x01},
|
||||
{0x01,0x1E},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x41,0x50},
|
||||
{0x43,0x34},
|
||||
{0x65,0xCE},
|
||||
{0x66,0x0B},
|
||||
{0x67,0xCE},
|
||||
{0x68,0x0B},
|
||||
{0x69,0xE9},
|
||||
{0x6A,0x05},
|
||||
{0x6B,0x50},
|
||||
{0x6C,0xC3},
|
||||
{0x6D,0x50},
|
||||
{0x6E,0xC3},
|
||||
{0x74,0x05},
|
||||
};
|
||||
|
||||
//Gesture register initializes array
|
||||
const unsigned char Init_Gesture_Array[][2] = {
|
||||
{0xEF,0x00},
|
||||
{0x41,0x00},
|
||||
{0x42,0x00},
|
||||
{0xEF,0x00},
|
||||
{0x48,0x3C},
|
||||
{0x49,0x00},
|
||||
{0x51,0x10},
|
||||
{0x83,0x20},
|
||||
{0x9F,0xF9},
|
||||
{0xEF,0x01},
|
||||
{0x01,0x1E},
|
||||
{0x02,0x0F},
|
||||
{0x03,0x10},
|
||||
{0x04,0x02},
|
||||
{0x41,0x40},
|
||||
{0x43,0x30},
|
||||
{0x65,0x96},
|
||||
{0x66,0x00},
|
||||
{0x67,0x97},
|
||||
{0x68,0x01},
|
||||
{0x69,0xCD},
|
||||
{0x6A,0x01},
|
||||
{0x6B,0xB0},
|
||||
{0x6C,0x04},
|
||||
{0x6D,0x2C},
|
||||
{0x6E,0x01},
|
||||
{0x74,0x00},
|
||||
{0xEF,0x00},
|
||||
{0x41,0xFF},
|
||||
{0x42,0x01},
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
[PreviousGenFiles]
|
||||
HeaderPath=F:/stm322/Gesture/Inc
|
||||
HeaderFiles=gpio.h;usart.h;stm32f1xx_it.h;stm32f1xx_hal_conf.h;main.h;i2c.h;
|
||||
SourcePath=F:/stm322/Gesture/Src
|
||||
SourceFiles=gpio.c;usart.c;stm32f1xx_it.c;stm32f1xx_hal_msp.c;main.c;i2c.c;
|
||||
|
||||
[PreviousLibFiles]
|
||||
LibFiles=Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h;Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h;Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h;Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c;Drivers/CMSIS/Include/arm_common_tables.h;Drivers/CMSIS/Include/arm_const_structs.h;Drivers/CMSIS/Include/arm_math.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armcc_V6.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_cmFunc.h;Drivers/CMSIS/Include/core_cmInstr.h;Drivers/CMSIS/Include/core_cmSimd.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h;
|
||||
|
||||
[PreviousUsedKeilFiles]
|
||||
SourceFiles=..\Src\main.c;..\Src\gpio.c;..\Src\i2c.c;..\Src\usart.c;..\Src\stm32f1xx_it.c;..\Src\stm32f1xx_hal_msp.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;../\Src/system_stm32f1xx.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;../\Src/system_stm32f1xx.c;../Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c;null;
|
||||
HeaderPath=..\Drivers\STM32F1xx_HAL_Driver\Inc;..\Drivers\STM32F1xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32F1xx\Include;..\Drivers\CMSIS\Include;..\Inc;
|
||||
CDefines=USE_HAL_DRIVER;STM32F103xB;
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_abs_f32.c
|
||||
*
|
||||
* Description: Vector absolute value.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup BasicAbs Vector Absolute Value
|
||||
*
|
||||
* Computes the absolute value of a vector on an element-by-element basis.
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = abs(pSrc[n]), 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* The functions support in-place computation allowing the source and
|
||||
* destination pointers to reference the same memory buffer.
|
||||
* There are separate functions for floating-point, Q7, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicAbs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Floating-point vector absolute value.
|
||||
* @param[in] *pSrc points to the input buffer
|
||||
* @param[out] *pDst points to the output buffer
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
void arm_abs_f32(
|
||||
float32_t * pSrc,
|
||||
float32_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
float32_t in1, in2, in3, in4; /* temporary variables */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Calculate absolute and then store the results in the destination buffer. */
|
||||
/* read sample from source */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
in3 = *(pSrc + 2);
|
||||
|
||||
/* find absolute value */
|
||||
in1 = fabsf(in1);
|
||||
|
||||
/* read sample from source */
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
/* find absolute value */
|
||||
in2 = fabsf(in2);
|
||||
|
||||
/* read sample from source */
|
||||
*pDst = in1;
|
||||
|
||||
/* find absolute value */
|
||||
in3 = fabsf(in3);
|
||||
|
||||
/* find absolute value */
|
||||
in4 = fabsf(in4);
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 1) = in2;
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 2) = in3;
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 3) = in4;
|
||||
|
||||
|
||||
/* Update source pointer to process next sampels */
|
||||
pSrc += 4u;
|
||||
|
||||
/* Update destination pointer to process next sampels */
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Calculate absolute and then store the results in the destination buffer. */
|
||||
*pDst++ = fabsf(*pSrc++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicAbs group
|
||||
*/
|
||||
@@ -0,0 +1,179 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_abs_q15.c
|
||||
*
|
||||
* Description: Q15 vector absolute value.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicAbs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q15 vector absolute value.
|
||||
* @param[in] *pSrc points to the input buffer
|
||||
* @param[out] *pDst points to the output buffer
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* The Q15 value -1 (0x8000) will be saturated to the maximum allowable positive value 0x7FFF.
|
||||
*/
|
||||
|
||||
void arm_abs_q15(
|
||||
q15_t * pSrc,
|
||||
q15_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
__SIMD32_TYPE *simd;
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
q15_t in1; /* Input value1 */
|
||||
q15_t in2; /* Input value2 */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
simd = __SIMD32_CONST(pDst);
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Read two inputs */
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
|
||||
|
||||
/* Store the Absolute result in the destination buffer by packing the two values, in a single cycle */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
*simd++ =
|
||||
__PKHBT(((in1 > 0) ? in1 : (q15_t)__QSUB16(0, in1)),
|
||||
((in2 > 0) ? in2 : (q15_t)__QSUB16(0, in2)), 16);
|
||||
|
||||
#else
|
||||
|
||||
|
||||
*simd++ =
|
||||
__PKHBT(((in2 > 0) ? in2 : (q15_t)__QSUB16(0, in2)),
|
||||
((in1 > 0) ? in1 : (q15_t)__QSUB16(0, in1)), 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*simd++ =
|
||||
__PKHBT(((in1 > 0) ? in1 : (q15_t)__QSUB16(0, in1)),
|
||||
((in2 > 0) ? in2 : (q15_t)__QSUB16(0, in2)), 16);
|
||||
|
||||
#else
|
||||
|
||||
|
||||
*simd++ =
|
||||
__PKHBT(((in2 > 0) ? in2 : (q15_t)__QSUB16(0, in2)),
|
||||
((in1 > 0) ? in1 : (q15_t)__QSUB16(0, in1)), 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
pDst = (q15_t *)simd;
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Read the input */
|
||||
in1 = *pSrc++;
|
||||
|
||||
/* Calculate absolute value of input and then store the result in the destination buffer. */
|
||||
*pDst++ = (in1 > 0) ? in1 : (q15_t)__QSUB16(0, in1);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
q15_t in; /* Temporary input variable */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Read the input */
|
||||
in = *pSrc++;
|
||||
|
||||
/* Calculate absolute value of input and then store the result in the destination buffer. */
|
||||
*pDst++ = (in > 0) ? in : ((in == (q15_t) 0x8000) ? 0x7fff : -in);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicAbs group
|
||||
*/
|
||||
@@ -0,0 +1,130 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_abs_q31.c
|
||||
*
|
||||
* Description: Q31 vector absolute value.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicAbs
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Q31 vector absolute value.
|
||||
* @param[in] *pSrc points to the input buffer
|
||||
* @param[out] *pDst points to the output buffer
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* The Q31 value -1 (0x80000000) will be saturated to the maximum allowable positive value 0x7FFFFFFF.
|
||||
*/
|
||||
|
||||
void arm_abs_q31(
|
||||
q31_t * pSrc,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
q31_t in; /* Input value */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t in1, in2, in3, in4;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Calculate absolute of input (if -1 then saturated to 0x7fffffff) and then store the results in the destination buffer. */
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
in3 = *pSrc++;
|
||||
in4 = *pSrc++;
|
||||
|
||||
*pDst++ = (in1 > 0) ? in1 : (q31_t)__QSUB(0, in1);
|
||||
*pDst++ = (in2 > 0) ? in2 : (q31_t)__QSUB(0, in2);
|
||||
*pDst++ = (in3 > 0) ? in3 : (q31_t)__QSUB(0, in3);
|
||||
*pDst++ = (in4 > 0) ? in4 : (q31_t)__QSUB(0, in4);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Calculate absolute value of the input (if -1 then saturated to 0x7fffffff) and then store the results in the destination buffer. */
|
||||
in = *pSrc++;
|
||||
*pDst++ = (in > 0) ? in : ((in == INT32_MIN) ? INT32_MAX : -in);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicAbs group
|
||||
*/
|
||||
@@ -0,0 +1,157 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_abs_q7.c
|
||||
*
|
||||
* Description: Q7 vector absolute value.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicAbs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q7 vector absolute value.
|
||||
* @param[in] *pSrc points to the input buffer
|
||||
* @param[out] *pDst points to the output buffer
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* \par Conditions for optimum performance
|
||||
* Input and output buffers should be aligned by 32-bit
|
||||
*
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* The Q7 value -1 (0x80) will be saturated to the maximum allowable positive value 0x7F.
|
||||
*/
|
||||
|
||||
void arm_abs_q7(
|
||||
q7_t * pSrc,
|
||||
q7_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
q7_t in; /* Input value1 */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t in1, in2, in3, in4; /* temporary input variables */
|
||||
q31_t out1, out2, out3, out4; /* temporary output variables */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Read inputs */
|
||||
in1 = (q31_t) * pSrc;
|
||||
in2 = (q31_t) * (pSrc + 1);
|
||||
in3 = (q31_t) * (pSrc + 2);
|
||||
|
||||
/* find absolute value */
|
||||
out1 = (in1 > 0) ? in1 : (q31_t)__QSUB8(0, in1);
|
||||
|
||||
/* read input */
|
||||
in4 = (q31_t) * (pSrc + 3);
|
||||
|
||||
/* find absolute value */
|
||||
out2 = (in2 > 0) ? in2 : (q31_t)__QSUB8(0, in2);
|
||||
|
||||
/* store result to destination */
|
||||
*pDst = (q7_t) out1;
|
||||
|
||||
/* find absolute value */
|
||||
out3 = (in3 > 0) ? in3 : (q31_t)__QSUB8(0, in3);
|
||||
|
||||
/* find absolute value */
|
||||
out4 = (in4 > 0) ? in4 : (q31_t)__QSUB8(0, in4);
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 1) = (q7_t) out2;
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 2) = (q7_t) out3;
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 3) = (q7_t) out4;
|
||||
|
||||
/* update pointers to process next samples */
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #define ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Read the input */
|
||||
in = *pSrc++;
|
||||
|
||||
/* Store the Absolute result in the destination buffer */
|
||||
*pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? 0x7f : -in);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicAbs group
|
||||
*/
|
||||
@@ -0,0 +1,150 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_add_f32.c
|
||||
*
|
||||
* Description: Floating-point vector addition.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup BasicAdd Vector Addition
|
||||
*
|
||||
* Element-by-element addition of two vectors.
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = pSrcA[n] + pSrcB[n], 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* There are separate functions for floating-point, Q7, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicAdd
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Floating-point vector addition.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
void arm_add_f32(
|
||||
float32_t * pSrcA,
|
||||
float32_t * pSrcB,
|
||||
float32_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
float32_t inA1, inA2, inA3, inA4; /* temporary input variabels */
|
||||
float32_t inB1, inB2, inB3, inB4; /* temporary input variables */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
|
||||
/* read four inputs from sourceA and four inputs from sourceB */
|
||||
inA1 = *pSrcA;
|
||||
inB1 = *pSrcB;
|
||||
inA2 = *(pSrcA + 1);
|
||||
inB2 = *(pSrcB + 1);
|
||||
inA3 = *(pSrcA + 2);
|
||||
inB3 = *(pSrcB + 2);
|
||||
inA4 = *(pSrcA + 3);
|
||||
inB4 = *(pSrcB + 3);
|
||||
|
||||
/* C = A + B */
|
||||
/* add and store result to destination */
|
||||
*pDst = inA1 + inB1;
|
||||
*(pDst + 1) = inA2 + inB2;
|
||||
*(pDst + 2) = inA3 + inB3;
|
||||
*(pDst + 3) = inA4 + inB4;
|
||||
|
||||
/* update pointers to process next samples */
|
||||
pSrcA += 4u;
|
||||
pSrcB += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
*pDst++ = (*pSrcA++) + (*pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicAdd group
|
||||
*/
|
||||
@@ -0,0 +1,140 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_add_q15.c
|
||||
*
|
||||
* Description: Q15 vector addition
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicAdd
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q15 vector addition.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_add_q15(
|
||||
q15_t * pSrcA,
|
||||
q15_t * pSrcB,
|
||||
q15_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t inA1, inA2, inB1, inB2;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
inA1 = *__SIMD32(pSrcA)++;
|
||||
inA2 = *__SIMD32(pSrcA)++;
|
||||
inB1 = *__SIMD32(pSrcB)++;
|
||||
inB2 = *__SIMD32(pSrcB)++;
|
||||
|
||||
*__SIMD32(pDst)++ = __QADD16(inA1, inB1);
|
||||
*__SIMD32(pDst)++ = __QADD16(inA2, inB2);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
*pDst++ = (q15_t) __QADD16(*pSrcA++, *pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
*pDst++ = (q15_t) __SSAT(((q31_t) * pSrcA++ + *pSrcB++), 16);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicAdd group
|
||||
*/
|
||||
@@ -0,0 +1,148 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_add_q31.c
|
||||
*
|
||||
* Description: Q31 vector addition.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicAdd
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Q31 vector addition.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q31 range[0x80000000 0x7FFFFFFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_add_q31(
|
||||
q31_t * pSrcA,
|
||||
q31_t * pSrcB,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t inA1, inA2, inA3, inA4;
|
||||
q31_t inB1, inB2, inB3, inB4;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
inA1 = *pSrcA++;
|
||||
inA2 = *pSrcA++;
|
||||
inB1 = *pSrcB++;
|
||||
inB2 = *pSrcB++;
|
||||
|
||||
inA3 = *pSrcA++;
|
||||
inA4 = *pSrcA++;
|
||||
inB3 = *pSrcB++;
|
||||
inB4 = *pSrcB++;
|
||||
|
||||
*pDst++ = __QADD(inA1, inB1);
|
||||
*pDst++ = __QADD(inA2, inB2);
|
||||
*pDst++ = __QADD(inA3, inB3);
|
||||
*pDst++ = __QADD(inA4, inB4);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
*pDst++ = __QADD(*pSrcA++, *pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
*pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrcA++ + *pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicAdd group
|
||||
*/
|
||||
@@ -0,0 +1,134 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_add_q7.c
|
||||
*
|
||||
* Description: Q7 vector addition.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicAdd
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q7 vector addition.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q7 range [0x80 0x7F] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_add_q7(
|
||||
q7_t * pSrcA,
|
||||
q7_t * pSrcB,
|
||||
q7_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
*__SIMD32(pDst)++ = __QADD8(*__SIMD32(pSrcA)++, *__SIMD32(pSrcB)++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
*pDst++ = (q7_t) __SSAT(*pSrcA++ + *pSrcB++, 8);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
*pDst++ = (q7_t) __SSAT((q15_t) * pSrcA++ + *pSrcB++, 8);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicAdd group
|
||||
*/
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_dot_prod_f32.c
|
||||
*
|
||||
* Description: Floating-point dot product.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup dot_prod Vector Dot Product
|
||||
*
|
||||
* Computes the dot product of two vectors.
|
||||
* The vectors are multiplied element-by-element and then summed.
|
||||
*
|
||||
* <pre>
|
||||
* sum = pSrcA[0]*pSrcB[0] + pSrcA[1]*pSrcB[1] + ... + pSrcA[blockSize-1]*pSrcB[blockSize-1]
|
||||
* </pre>
|
||||
*
|
||||
* There are separate functions for floating-point, Q7, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup dot_prod
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Dot product of floating-point vectors.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @param[out] *result output result returned here
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
|
||||
void arm_dot_prod_f32(
|
||||
float32_t * pSrcA,
|
||||
float32_t * pSrcB,
|
||||
uint32_t blockSize,
|
||||
float32_t * result)
|
||||
{
|
||||
float32_t sum = 0.0f; /* Temporary result storage */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Calculate dot product and then store the result in a temporary buffer */
|
||||
sum += (*pSrcA++) * (*pSrcB++);
|
||||
sum += (*pSrcA++) * (*pSrcB++);
|
||||
sum += (*pSrcA++) * (*pSrcB++);
|
||||
sum += (*pSrcA++) * (*pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Calculate dot product and then store the result in a temporary buffer. */
|
||||
sum += (*pSrcA++) * (*pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
/* Store the result back in the destination buffer */
|
||||
*result = sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of dot_prod group
|
||||
*/
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_dot_prod_q15.c
|
||||
*
|
||||
* Description: Q15 dot product.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup dot_prod
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Dot product of Q15 vectors.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @param[out] *result output result returned here
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The intermediate multiplications are in 1.15 x 1.15 = 2.30 format and these
|
||||
* results are added to a 64-bit accumulator in 34.30 format.
|
||||
* Nonsaturating additions are used and given that there are 33 guard bits in the accumulator
|
||||
* there is no risk of overflow.
|
||||
* The return result is in 34.30 format.
|
||||
*/
|
||||
|
||||
void arm_dot_prod_q15(
|
||||
q15_t * pSrcA,
|
||||
q15_t * pSrcB,
|
||||
uint32_t blockSize,
|
||||
q63_t * result)
|
||||
{
|
||||
q63_t sum = 0; /* Temporary result storage */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Calculate dot product and then store the result in a temporary buffer. */
|
||||
sum = __SMLALD(*__SIMD32(pSrcA)++, *__SIMD32(pSrcB)++, sum);
|
||||
sum = __SMLALD(*__SIMD32(pSrcA)++, *__SIMD32(pSrcB)++, sum);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Calculate dot product and then store the results in a temporary buffer. */
|
||||
sum = __SMLALD(*pSrcA++, *pSrcB++, sum);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Calculate dot product and then store the results in a temporary buffer. */
|
||||
sum += (q63_t) ((q31_t) * pSrcA++ * *pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
/* Store the result in the destination buffer in 34.30 format */
|
||||
*result = sum;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of dot_prod group
|
||||
*/
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_dot_prod_q31.c
|
||||
*
|
||||
* Description: Q31 dot product.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup dot_prod
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Dot product of Q31 vectors.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @param[out] *result output result returned here
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The intermediate multiplications are in 1.31 x 1.31 = 2.62 format and these
|
||||
* are truncated to 2.48 format by discarding the lower 14 bits.
|
||||
* The 2.48 result is then added without saturation to a 64-bit accumulator in 16.48 format.
|
||||
* There are 15 guard bits in the accumulator and there is no risk of overflow as long as
|
||||
* the length of the vectors is less than 2^16 elements.
|
||||
* The return result is in 16.48 format.
|
||||
*/
|
||||
|
||||
void arm_dot_prod_q31(
|
||||
q31_t * pSrcA,
|
||||
q31_t * pSrcB,
|
||||
uint32_t blockSize,
|
||||
q63_t * result)
|
||||
{
|
||||
q63_t sum = 0; /* Temporary result storage */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t inA1, inA2, inA3, inA4;
|
||||
q31_t inB1, inB2, inB3, inB4;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Calculate dot product and then store the result in a temporary buffer. */
|
||||
inA1 = *pSrcA++;
|
||||
inA2 = *pSrcA++;
|
||||
inA3 = *pSrcA++;
|
||||
inA4 = *pSrcA++;
|
||||
inB1 = *pSrcB++;
|
||||
inB2 = *pSrcB++;
|
||||
inB3 = *pSrcB++;
|
||||
inB4 = *pSrcB++;
|
||||
|
||||
sum += ((q63_t) inA1 * inB1) >> 14u;
|
||||
sum += ((q63_t) inA2 * inB2) >> 14u;
|
||||
sum += ((q63_t) inA3 * inB3) >> 14u;
|
||||
sum += ((q63_t) inA4 * inB4) >> 14u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Calculate dot product and then store the result in a temporary buffer. */
|
||||
sum += ((q63_t) * pSrcA++ * *pSrcB++) >> 14u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* Store the result in the destination buffer in 16.48 format */
|
||||
*result = sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of dot_prod group
|
||||
*/
|
||||
@@ -0,0 +1,159 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_dot_prod_q7.c
|
||||
*
|
||||
* Description: Q7 dot product.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup dot_prod
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Dot product of Q7 vectors.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @param[out] *result output result returned here
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The intermediate multiplications are in 1.7 x 1.7 = 2.14 format and these
|
||||
* results are added to an accumulator in 18.14 format.
|
||||
* Nonsaturating additions are used and there is no danger of wrap around as long as
|
||||
* the vectors are less than 2^18 elements long.
|
||||
* The return result is in 18.14 format.
|
||||
*/
|
||||
|
||||
void arm_dot_prod_q7(
|
||||
q7_t * pSrcA,
|
||||
q7_t * pSrcB,
|
||||
uint32_t blockSize,
|
||||
q31_t * result)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
q31_t sum = 0; /* Temporary variables to store output */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
q31_t input1, input2; /* Temporary variables to store input */
|
||||
q31_t inA1, inA2, inB1, inB2; /* Temporary variables to store input */
|
||||
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* read 4 samples at a time from sourceA */
|
||||
input1 = *__SIMD32(pSrcA)++;
|
||||
/* read 4 samples at a time from sourceB */
|
||||
input2 = *__SIMD32(pSrcB)++;
|
||||
|
||||
/* extract two q7_t samples to q15_t samples */
|
||||
inA1 = __SXTB16(__ROR(input1, 8));
|
||||
/* extract reminaing two samples */
|
||||
inA2 = __SXTB16(input1);
|
||||
/* extract two q7_t samples to q15_t samples */
|
||||
inB1 = __SXTB16(__ROR(input2, 8));
|
||||
/* extract reminaing two samples */
|
||||
inB2 = __SXTB16(input2);
|
||||
|
||||
/* multiply and accumulate two samples at a time */
|
||||
sum = __SMLAD(inA1, inB1, sum);
|
||||
sum = __SMLAD(inA2, inB2, sum);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Dot product and then store the results in a temporary buffer. */
|
||||
sum = __SMLAD(*pSrcA++, *pSrcB++, sum);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Dot product and then store the results in a temporary buffer. */
|
||||
sum += (q31_t) ((q15_t) * pSrcA++ * *pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
/* Store the result in the destination buffer in 18.14 format */
|
||||
*result = sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of dot_prod group
|
||||
*/
|
||||
@@ -0,0 +1,174 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mult_f32.c
|
||||
*
|
||||
* Description: Floating-point vector multiplication.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup BasicMult Vector Multiplication
|
||||
*
|
||||
* Element-by-element multiplication of two vectors.
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = pSrcA[n] * pSrcB[n], 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* There are separate functions for floating-point, Q7, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Floating-point vector multiplication.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
void arm_mult_f32(
|
||||
float32_t * pSrcA,
|
||||
float32_t * pSrcB,
|
||||
float32_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
float32_t inA1, inA2, inA3, inA4; /* temporary input variables */
|
||||
float32_t inB1, inB2, inB3, inB4; /* temporary input variables */
|
||||
float32_t out1, out2, out3, out4; /* temporary output variables */
|
||||
|
||||
/* loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * B */
|
||||
/* Multiply the inputs and store the results in output buffer */
|
||||
/* read sample from sourceA */
|
||||
inA1 = *pSrcA;
|
||||
/* read sample from sourceB */
|
||||
inB1 = *pSrcB;
|
||||
/* read sample from sourceA */
|
||||
inA2 = *(pSrcA + 1);
|
||||
/* read sample from sourceB */
|
||||
inB2 = *(pSrcB + 1);
|
||||
|
||||
/* out = sourceA * sourceB */
|
||||
out1 = inA1 * inB1;
|
||||
|
||||
/* read sample from sourceA */
|
||||
inA3 = *(pSrcA + 2);
|
||||
/* read sample from sourceB */
|
||||
inB3 = *(pSrcB + 2);
|
||||
|
||||
/* out = sourceA * sourceB */
|
||||
out2 = inA2 * inB2;
|
||||
|
||||
/* read sample from sourceA */
|
||||
inA4 = *(pSrcA + 3);
|
||||
|
||||
/* store result to destination buffer */
|
||||
*pDst = out1;
|
||||
|
||||
/* read sample from sourceB */
|
||||
inB4 = *(pSrcB + 3);
|
||||
|
||||
/* out = sourceA * sourceB */
|
||||
out3 = inA3 * inB3;
|
||||
|
||||
/* store result to destination buffer */
|
||||
*(pDst + 1) = out2;
|
||||
|
||||
/* out = sourceA * sourceB */
|
||||
out4 = inA4 * inB4;
|
||||
/* store result to destination buffer */
|
||||
*(pDst + 2) = out3;
|
||||
/* store result to destination buffer */
|
||||
*(pDst + 3) = out4;
|
||||
|
||||
|
||||
/* update pointers to process next samples */
|
||||
pSrcA += 4u;
|
||||
pSrcB += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * B */
|
||||
/* Multiply the inputs and store the results in output buffer */
|
||||
*pDst++ = (*pSrcA++) * (*pSrcB++);
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicMult group
|
||||
*/
|
||||
@@ -0,0 +1,154 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. October 2015
|
||||
* $Revision: V.1.4.5 a
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mult_q15.c
|
||||
*
|
||||
* Description: Q15 vector multiplication.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Q15 vector multiplication
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_mult_q15(
|
||||
q15_t * pSrcA,
|
||||
q15_t * pSrcB,
|
||||
q15_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t inA1, inA2, inB1, inB2; /* temporary input variables */
|
||||
q15_t out1, out2, out3, out4; /* temporary output variables */
|
||||
q31_t mul1, mul2, mul3, mul4; /* temporary variables */
|
||||
|
||||
/* loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* read two samples at a time from sourceA */
|
||||
inA1 = *__SIMD32(pSrcA)++;
|
||||
/* read two samples at a time from sourceB */
|
||||
inB1 = *__SIMD32(pSrcB)++;
|
||||
/* read two samples at a time from sourceA */
|
||||
inA2 = *__SIMD32(pSrcA)++;
|
||||
/* read two samples at a time from sourceB */
|
||||
inB2 = *__SIMD32(pSrcB)++;
|
||||
|
||||
/* multiply mul = sourceA * sourceB */
|
||||
mul1 = (q31_t) ((q15_t) (inA1 >> 16) * (q15_t) (inB1 >> 16));
|
||||
mul2 = (q31_t) ((q15_t) inA1 * (q15_t) inB1);
|
||||
mul3 = (q31_t) ((q15_t) (inA2 >> 16) * (q15_t) (inB2 >> 16));
|
||||
mul4 = (q31_t) ((q15_t) inA2 * (q15_t) inB2);
|
||||
|
||||
/* saturate result to 16 bit */
|
||||
out1 = (q15_t) __SSAT(mul1 >> 15, 16);
|
||||
out2 = (q15_t) __SSAT(mul2 >> 15, 16);
|
||||
out3 = (q15_t) __SSAT(mul3 >> 15, 16);
|
||||
out4 = (q15_t) __SSAT(mul4 >> 15, 16);
|
||||
|
||||
/* store the result */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT(out2, out1, 16);
|
||||
*__SIMD32(pDst)++ = __PKHBT(out4, out3, 16);
|
||||
|
||||
#else
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT(out2, out1, 16);
|
||||
*__SIMD32(pDst)++ = __PKHBT(out4, out3, 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * B */
|
||||
/* Multiply the inputs and store the result in the destination buffer */
|
||||
*pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++)) >> 15), 16);
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicMult group
|
||||
*/
|
||||
@@ -0,0 +1,160 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mult_q31.c
|
||||
*
|
||||
* Description: Q31 vector multiplication.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q31 vector multiplication.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q31 range[0x80000000 0x7FFFFFFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_mult_q31(
|
||||
q31_t * pSrcA,
|
||||
q31_t * pSrcB,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t inA1, inA2, inA3, inA4; /* temporary input variables */
|
||||
q31_t inB1, inB2, inB3, inB4; /* temporary input variables */
|
||||
q31_t out1, out2, out3, out4; /* temporary output variables */
|
||||
|
||||
/* loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * B */
|
||||
/* Multiply the inputs and then store the results in the destination buffer. */
|
||||
inA1 = *pSrcA++;
|
||||
inA2 = *pSrcA++;
|
||||
inA3 = *pSrcA++;
|
||||
inA4 = *pSrcA++;
|
||||
inB1 = *pSrcB++;
|
||||
inB2 = *pSrcB++;
|
||||
inB3 = *pSrcB++;
|
||||
inB4 = *pSrcB++;
|
||||
|
||||
out1 = ((q63_t) inA1 * inB1) >> 32;
|
||||
out2 = ((q63_t) inA2 * inB2) >> 32;
|
||||
out3 = ((q63_t) inA3 * inB3) >> 32;
|
||||
out4 = ((q63_t) inA4 * inB4) >> 32;
|
||||
|
||||
out1 = __SSAT(out1, 31);
|
||||
out2 = __SSAT(out2, 31);
|
||||
out3 = __SSAT(out3, 31);
|
||||
out4 = __SSAT(out4, 31);
|
||||
|
||||
*pDst++ = out1 << 1u;
|
||||
*pDst++ = out2 << 1u;
|
||||
*pDst++ = out3 << 1u;
|
||||
*pDst++ = out4 << 1u;
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * B */
|
||||
/* Multiply the inputs and then store the results in the destination buffer. */
|
||||
inA1 = *pSrcA++;
|
||||
inB1 = *pSrcB++;
|
||||
out1 = ((q63_t) inA1 * inB1) >> 32;
|
||||
out1 = __SSAT(out1, 31);
|
||||
*pDst++ = out1 << 1u;
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * B */
|
||||
/* Multiply the inputs and then store the results in the destination buffer. */
|
||||
*pDst++ =
|
||||
(q31_t) clip_q63_to_q31(((q63_t) (*pSrcA++) * (*pSrcB++)) >> 31);
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicMult group
|
||||
*/
|
||||
@@ -0,0 +1,127 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mult_q7.c
|
||||
*
|
||||
* Description: Q7 vector multiplication.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q7 vector multiplication
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q7 range [0x80 0x7F] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_mult_q7(
|
||||
q7_t * pSrcA,
|
||||
q7_t * pSrcB,
|
||||
q7_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q7_t out1, out2, out3, out4; /* Temporary variables to store the product */
|
||||
|
||||
/* loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * B */
|
||||
/* Multiply the inputs and store the results in temporary variables */
|
||||
out1 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
|
||||
out2 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
|
||||
out3 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
|
||||
out4 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
|
||||
|
||||
/* Store the results of 4 inputs in the destination buffer in single cycle by packing */
|
||||
*__SIMD32(pDst)++ = __PACKq7(out1, out2, out3, out4);
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * B */
|
||||
/* Multiply the inputs and store the result in the destination buffer */
|
||||
*pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicMult group
|
||||
*/
|
||||
@@ -0,0 +1,146 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_negate_f32.c
|
||||
*
|
||||
* Description: Negates floating-point vectors.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup negate Vector Negate
|
||||
*
|
||||
* Negates the elements of a vector.
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = -pSrc[n], 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* The functions support in-place computation allowing the source and
|
||||
* destination pointers to reference the same memory buffer.
|
||||
* There are separate functions for floating-point, Q7, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup negate
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Negates the elements of a floating-point vector.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
void arm_negate_f32(
|
||||
float32_t * pSrc,
|
||||
float32_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
float32_t in1, in2, in3, in4; /* temporary variables */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* read inputs from source */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
in3 = *(pSrc + 2);
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
/* negate the input */
|
||||
in1 = -in1;
|
||||
in2 = -in2;
|
||||
in3 = -in3;
|
||||
in4 = -in4;
|
||||
|
||||
/* store the result to destination */
|
||||
*pDst = in1;
|
||||
*(pDst + 1) = in2;
|
||||
*(pDst + 2) = in3;
|
||||
*(pDst + 3) = in4;
|
||||
|
||||
/* update pointers to process next samples */
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = -A */
|
||||
/* Negate and then store the results in the destination buffer. */
|
||||
*pDst++ = -*pSrc++;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of negate group
|
||||
*/
|
||||
@@ -0,0 +1,142 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_negate_q15.c
|
||||
*
|
||||
* Description: Negates Q15 vectors.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup negate
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Negates the elements of a Q15 vector.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* \par Conditions for optimum performance
|
||||
* Input and output buffers should be aligned by 32-bit
|
||||
*
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* The Q15 value -1 (0x8000) will be saturated to the maximum allowable positive value 0x7FFF.
|
||||
*/
|
||||
|
||||
void arm_negate_q15(
|
||||
q15_t * pSrc,
|
||||
q15_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
q15_t in;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
q31_t in1, in2; /* Temporary variables */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = -A */
|
||||
/* Read two inputs at a time */
|
||||
in1 = _SIMD32_OFFSET(pSrc);
|
||||
in2 = _SIMD32_OFFSET(pSrc + 2);
|
||||
|
||||
/* negate two samples at a time */
|
||||
in1 = __QSUB16(0, in1);
|
||||
|
||||
/* negate two samples at a time */
|
||||
in2 = __QSUB16(0, in2);
|
||||
|
||||
/* store the result to destination 2 samples at a time */
|
||||
_SIMD32_OFFSET(pDst) = in1;
|
||||
/* store the result to destination 2 samples at a time */
|
||||
_SIMD32_OFFSET(pDst + 2) = in2;
|
||||
|
||||
|
||||
/* update pointers to process next samples */
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = -A */
|
||||
/* Negate and then store the result in the destination buffer. */
|
||||
in = *pSrc++;
|
||||
*pDst++ = (in == (q15_t) 0x8000) ? 0x7fff : -in;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of negate group
|
||||
*/
|
||||
@@ -0,0 +1,129 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_negate_q31.c
|
||||
*
|
||||
* Description: Negates Q31 vectors.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup negate
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Negates the elements of a Q31 vector.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* The Q31 value -1 (0x80000000) will be saturated to the maximum allowable positive value 0x7FFFFFFF.
|
||||
*/
|
||||
|
||||
void arm_negate_q31(
|
||||
q31_t * pSrc,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
q31_t in; /* Temporary variable */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t in1, in2, in3, in4;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = -A */
|
||||
/* Negate and then store the results in the destination buffer. */
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
in3 = *pSrc++;
|
||||
in4 = *pSrc++;
|
||||
|
||||
*pDst++ = __QSUB(0, in1);
|
||||
*pDst++ = __QSUB(0, in2);
|
||||
*pDst++ = __QSUB(0, in3);
|
||||
*pDst++ = __QSUB(0, in4);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = -A */
|
||||
/* Negate and then store the result in the destination buffer. */
|
||||
in = *pSrc++;
|
||||
*pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of negate group
|
||||
*/
|
||||
@@ -0,0 +1,125 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_negate_q7.c
|
||||
*
|
||||
* Description: Negates Q7 vectors.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup negate
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Negates the elements of a Q7 vector.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* The Q7 value -1 (0x80) will be saturated to the maximum allowable positive value 0x7F.
|
||||
*/
|
||||
|
||||
void arm_negate_q7(
|
||||
q7_t * pSrc,
|
||||
q7_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
q7_t in;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t input; /* Input values1-4 */
|
||||
q31_t zero = 0x00000000;
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = -A */
|
||||
/* Read four inputs */
|
||||
input = *__SIMD32(pSrc)++;
|
||||
|
||||
/* Store the Negated results in the destination buffer in a single cycle by packing the results */
|
||||
*__SIMD32(pDst)++ = __QSUB8(zero, input);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = -A */
|
||||
/* Negate and then store the results in the destination buffer. */ \
|
||||
in = *pSrc++;
|
||||
*pDst++ = (in == (q7_t) 0x80) ? 0x7f : -in;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of negate group
|
||||
*/
|
||||
@@ -0,0 +1,165 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_offset_f32.c
|
||||
*
|
||||
* Description: Floating-point vector offset.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------- */
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup offset Vector Offset
|
||||
*
|
||||
* Adds a constant offset to each element of a vector.
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = pSrc[n] + offset, 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* The functions support in-place computation allowing the source and
|
||||
* destination pointers to reference the same memory buffer.
|
||||
* There are separate functions for floating-point, Q7, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup offset
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Adds a constant offset to a floating-point vector.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] offset is the offset to be added
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
|
||||
void arm_offset_f32(
|
||||
float32_t * pSrc,
|
||||
float32_t offset,
|
||||
float32_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
float32_t in1, in2, in3, in4;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the results in the destination buffer. */
|
||||
/* read samples from source */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
|
||||
/* add offset to input */
|
||||
in1 = in1 + offset;
|
||||
|
||||
/* read samples from source */
|
||||
in3 = *(pSrc + 2);
|
||||
|
||||
/* add offset to input */
|
||||
in2 = in2 + offset;
|
||||
|
||||
/* read samples from source */
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
/* add offset to input */
|
||||
in3 = in3 + offset;
|
||||
|
||||
/* store result to destination */
|
||||
*pDst = in1;
|
||||
|
||||
/* add offset to input */
|
||||
in4 = in4 + offset;
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 1) = in2;
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 2) = in3;
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 3) = in4;
|
||||
|
||||
/* update pointers to process next samples */
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the result in the destination buffer. */
|
||||
*pDst++ = (*pSrc++) + offset;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of offset group
|
||||
*/
|
||||
@@ -0,0 +1,136 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_offset_q15.c
|
||||
*
|
||||
* Description: Q15 vector offset.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup offset
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Adds a constant offset to a Q15 vector.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] offset is the offset to be added
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated.
|
||||
*/
|
||||
|
||||
void arm_offset_q15(
|
||||
q15_t * pSrc,
|
||||
q15_t offset,
|
||||
q15_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t offset_packed; /* Offset packed to 32 bit */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* Offset is packed to 32 bit in order to use SIMD32 for addition */
|
||||
offset_packed = __PKHBT(offset, offset, 16);
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the results in the destination buffer, 2 samples at a time. */
|
||||
*__SIMD32(pDst)++ = __QADD16(*__SIMD32(pSrc)++, offset_packed);
|
||||
*__SIMD32(pDst)++ = __QADD16(*__SIMD32(pSrc)++, offset_packed);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the results in the destination buffer. */
|
||||
*pDst++ = (q15_t) __QADD16(*pSrc++, offset);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the results in the destination buffer. */
|
||||
*pDst++ = (q15_t) __SSAT(((q31_t) * pSrc++ + offset), 16);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of offset group
|
||||
*/
|
||||
@@ -0,0 +1,140 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_offset_q31.c
|
||||
*
|
||||
* Description: Q31 vector offset.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup offset
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Adds a constant offset to a Q31 vector.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] offset is the offset to be added
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] are saturated.
|
||||
*/
|
||||
|
||||
void arm_offset_q31(
|
||||
q31_t * pSrc,
|
||||
q31_t offset,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t in1, in2, in3, in4;
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the results in the destination buffer. */
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
in3 = *pSrc++;
|
||||
in4 = *pSrc++;
|
||||
|
||||
*pDst++ = __QADD(in1, offset);
|
||||
*pDst++ = __QADD(in2, offset);
|
||||
*pDst++ = __QADD(in3, offset);
|
||||
*pDst++ = __QADD(in4, offset);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the result in the destination buffer. */
|
||||
*pDst++ = __QADD(*pSrc++, offset);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the result in the destination buffer. */
|
||||
*pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrc++ + offset);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of offset group
|
||||
*/
|
||||
@@ -0,0 +1,135 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_offset_q7.c
|
||||
*
|
||||
* Description: Q7 vector offset.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup offset
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Adds a constant offset to a Q7 vector.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] offset is the offset to be added
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q7 range [0x80 0x7F] are saturated.
|
||||
*/
|
||||
|
||||
void arm_offset_q7(
|
||||
q7_t * pSrc,
|
||||
q7_t offset,
|
||||
q7_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t offset_packed; /* Offset packed to 32 bit */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* Offset is packed to 32 bit in order to use SIMD32 for addition */
|
||||
offset_packed = __PACKq7(offset, offset, offset, offset);
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the results in the destination bufferfor 4 samples at a time. */
|
||||
*__SIMD32(pDst)++ = __QADD8(*__SIMD32(pSrc)++, offset_packed);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the result in the destination buffer. */
|
||||
*pDst++ = (q7_t) __SSAT(*pSrc++ + offset, 8);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the result in the destination buffer. */
|
||||
*pDst++ = (q7_t) __SSAT((q15_t) * pSrc++ + offset, 8);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of offset group
|
||||
*/
|
||||
@@ -0,0 +1,169 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_scale_f32.c
|
||||
*
|
||||
* Description: Multiplies a floating-point vector by a scalar.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup scale Vector Scale
|
||||
*
|
||||
* Multiply a vector by a scalar value. For floating-point data, the algorithm used is:
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = pSrc[n] * scale, 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* In the fixed-point Q7, Q15, and Q31 functions, <code>scale</code> is represented by
|
||||
* a fractional multiplication <code>scaleFract</code> and an arithmetic shift <code>shift</code>.
|
||||
* The shift allows the gain of the scaling operation to exceed 1.0.
|
||||
* The algorithm used with fixed-point data is:
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = (pSrc[n] * scaleFract) << shift, 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* The overall scale factor applied to the fixed-point data is
|
||||
* <pre>
|
||||
* scale = scaleFract * 2^shift.
|
||||
* </pre>
|
||||
*
|
||||
* The functions support in-place computation allowing the source and destination
|
||||
* pointers to reference the same memory buffer.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup scale
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Multiplies a floating-point vector by a scalar.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] scale scale factor to be applied
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
|
||||
void arm_scale_f32(
|
||||
float32_t * pSrc,
|
||||
float32_t scale,
|
||||
float32_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
float32_t in1, in2, in3, in4; /* temporary variabels */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * scale */
|
||||
/* Scale the input and then store the results in the destination buffer. */
|
||||
/* read input samples from source */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
|
||||
/* multiply with scaling factor */
|
||||
in1 = in1 * scale;
|
||||
|
||||
/* read input sample from source */
|
||||
in3 = *(pSrc + 2);
|
||||
|
||||
/* multiply with scaling factor */
|
||||
in2 = in2 * scale;
|
||||
|
||||
/* read input sample from source */
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
/* multiply with scaling factor */
|
||||
in3 = in3 * scale;
|
||||
in4 = in4 * scale;
|
||||
/* store the result to destination */
|
||||
*pDst = in1;
|
||||
*(pDst + 1) = in2;
|
||||
*(pDst + 2) = in3;
|
||||
*(pDst + 3) = in4;
|
||||
|
||||
/* update pointers to process next samples */
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * scale */
|
||||
/* Scale the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (*pSrc++) * scale;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of scale group
|
||||
*/
|
||||
@@ -0,0 +1,162 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_scale_q15.c
|
||||
*
|
||||
* Description: Multiplies a Q15 vector by a scalar.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup scale
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Multiplies a Q15 vector by a scalar.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] scaleFract fractional portion of the scale value
|
||||
* @param[in] shift number of bits to shift the result by
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The input data <code>*pSrc</code> and <code>scaleFract</code> are in 1.15 format.
|
||||
* These are multiplied to yield a 2.30 intermediate result and this is shifted with saturation to 1.15 format.
|
||||
*/
|
||||
|
||||
|
||||
void arm_scale_q15(
|
||||
q15_t * pSrc,
|
||||
q15_t scaleFract,
|
||||
int8_t shift,
|
||||
q15_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
int8_t kShift = 15 - shift; /* shift to apply after scaling */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q15_t in1, in2, in3, in4;
|
||||
q31_t inA1, inA2; /* Temporary variables */
|
||||
q31_t out1, out2, out3, out4;
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* Reading 2 inputs from memory */
|
||||
inA1 = *__SIMD32(pSrc)++;
|
||||
inA2 = *__SIMD32(pSrc)++;
|
||||
|
||||
/* C = A * scale */
|
||||
/* Scale the inputs and then store the 2 results in the destination buffer
|
||||
* in single cycle by packing the outputs */
|
||||
out1 = (q31_t) ((q15_t) (inA1 >> 16) * scaleFract);
|
||||
out2 = (q31_t) ((q15_t) inA1 * scaleFract);
|
||||
out3 = (q31_t) ((q15_t) (inA2 >> 16) * scaleFract);
|
||||
out4 = (q31_t) ((q15_t) inA2 * scaleFract);
|
||||
|
||||
/* apply shifting */
|
||||
out1 = out1 >> kShift;
|
||||
out2 = out2 >> kShift;
|
||||
out3 = out3 >> kShift;
|
||||
out4 = out4 >> kShift;
|
||||
|
||||
/* saturate the output */
|
||||
in1 = (q15_t) (__SSAT(out1, 16));
|
||||
in2 = (q15_t) (__SSAT(out2, 16));
|
||||
in3 = (q15_t) (__SSAT(out3, 16));
|
||||
in4 = (q15_t) (__SSAT(out4, 16));
|
||||
|
||||
/* store the result to destination */
|
||||
*__SIMD32(pDst)++ = __PKHBT(in2, in1, 16);
|
||||
*__SIMD32(pDst)++ = __PKHBT(in4, in3, 16);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * scale */
|
||||
/* Scale the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (q15_t) (__SSAT(((*pSrc++) * scaleFract) >> kShift, 16));
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * scale */
|
||||
/* Scale the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (q15_t) (__SSAT(((q31_t) * pSrc++ * scaleFract) >> kShift, 16));
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of scale group
|
||||
*/
|
||||
@@ -0,0 +1,239 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_scale_q31.c
|
||||
*
|
||||
* Description: Multiplies a Q31 vector by a scalar.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup scale
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Multiplies a Q31 vector by a scalar.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] scaleFract fractional portion of the scale value
|
||||
* @param[in] shift number of bits to shift the result by
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The input data <code>*pSrc</code> and <code>scaleFract</code> are in 1.31 format.
|
||||
* These are multiplied to yield a 2.62 intermediate result and this is shifted with saturation to 1.31 format.
|
||||
*/
|
||||
|
||||
void arm_scale_q31(
|
||||
q31_t * pSrc,
|
||||
q31_t scaleFract,
|
||||
int8_t shift,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
int8_t kShift = shift + 1; /* Shift to apply after scaling */
|
||||
int8_t sign = (kShift & 0x80);
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
q31_t in, out;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
q31_t in1, in2, in3, in4; /* temporary input variables */
|
||||
q31_t out1, out2, out3, out4; /* temporary output variabels */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
if(sign == 0u)
|
||||
{
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* read four inputs from source */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
in3 = *(pSrc + 2);
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
/* multiply input with scaler value */
|
||||
in1 = ((q63_t) in1 * scaleFract) >> 32;
|
||||
in2 = ((q63_t) in2 * scaleFract) >> 32;
|
||||
in3 = ((q63_t) in3 * scaleFract) >> 32;
|
||||
in4 = ((q63_t) in4 * scaleFract) >> 32;
|
||||
|
||||
/* apply shifting */
|
||||
out1 = in1 << kShift;
|
||||
out2 = in2 << kShift;
|
||||
|
||||
/* saturate the results. */
|
||||
if(in1 != (out1 >> kShift))
|
||||
out1 = 0x7FFFFFFF ^ (in1 >> 31);
|
||||
|
||||
if(in2 != (out2 >> kShift))
|
||||
out2 = 0x7FFFFFFF ^ (in2 >> 31);
|
||||
|
||||
out3 = in3 << kShift;
|
||||
out4 = in4 << kShift;
|
||||
|
||||
*pDst = out1;
|
||||
*(pDst + 1) = out2;
|
||||
|
||||
if(in3 != (out3 >> kShift))
|
||||
out3 = 0x7FFFFFFF ^ (in3 >> 31);
|
||||
|
||||
if(in4 != (out4 >> kShift))
|
||||
out4 = 0x7FFFFFFF ^ (in4 >> 31);
|
||||
|
||||
/* Store result destination */
|
||||
*(pDst + 2) = out3;
|
||||
*(pDst + 3) = out4;
|
||||
|
||||
/* Update pointers to process next sampels */
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* read four inputs from source */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
in3 = *(pSrc + 2);
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
/* multiply input with scaler value */
|
||||
in1 = ((q63_t) in1 * scaleFract) >> 32;
|
||||
in2 = ((q63_t) in2 * scaleFract) >> 32;
|
||||
in3 = ((q63_t) in3 * scaleFract) >> 32;
|
||||
in4 = ((q63_t) in4 * scaleFract) >> 32;
|
||||
|
||||
/* apply shifting */
|
||||
out1 = in1 >> -kShift;
|
||||
out2 = in2 >> -kShift;
|
||||
|
||||
out3 = in3 >> -kShift;
|
||||
out4 = in4 >> -kShift;
|
||||
|
||||
/* Store result destination */
|
||||
*pDst = out1;
|
||||
*(pDst + 1) = out2;
|
||||
|
||||
*(pDst + 2) = out3;
|
||||
*(pDst + 3) = out4;
|
||||
|
||||
/* Update pointers to process next sampels */
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
if(sign == 0)
|
||||
{
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * scale */
|
||||
/* Scale the input and then store the result in the destination buffer. */
|
||||
in = *pSrc++;
|
||||
in = ((q63_t) in * scaleFract) >> 32;
|
||||
|
||||
out = in << kShift;
|
||||
|
||||
if(in != (out >> kShift))
|
||||
out = 0x7FFFFFFF ^ (in >> 31);
|
||||
|
||||
*pDst++ = out;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * scale */
|
||||
/* Scale the input and then store the result in the destination buffer. */
|
||||
in = *pSrc++;
|
||||
in = ((q63_t) in * scaleFract) >> 32;
|
||||
|
||||
out = in >> -kShift;
|
||||
|
||||
*pDst++ = out;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of scale group
|
||||
*/
|
||||
@@ -0,0 +1,149 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_scale_q7.c
|
||||
*
|
||||
* Description: Multiplies a Q7 vector by a scalar.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup scale
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Multiplies a Q7 vector by a scalar.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] scaleFract fractional portion of the scale value
|
||||
* @param[in] shift number of bits to shift the result by
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The input data <code>*pSrc</code> and <code>scaleFract</code> are in 1.7 format.
|
||||
* These are multiplied to yield a 2.14 intermediate result and this is shifted with saturation to 1.7 format.
|
||||
*/
|
||||
|
||||
void arm_scale_q7(
|
||||
q7_t * pSrc,
|
||||
q7_t scaleFract,
|
||||
int8_t shift,
|
||||
q7_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
int8_t kShift = 7 - shift; /* shift to apply after scaling */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q7_t in1, in2, in3, in4, out1, out2, out3, out4; /* Temporary variables to store input & output */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* Reading 4 inputs from memory */
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
in3 = *pSrc++;
|
||||
in4 = *pSrc++;
|
||||
|
||||
/* C = A * scale */
|
||||
/* Scale the inputs and then store the results in the temporary variables. */
|
||||
out1 = (q7_t) (__SSAT(((in1) * scaleFract) >> kShift, 8));
|
||||
out2 = (q7_t) (__SSAT(((in2) * scaleFract) >> kShift, 8));
|
||||
out3 = (q7_t) (__SSAT(((in3) * scaleFract) >> kShift, 8));
|
||||
out4 = (q7_t) (__SSAT(((in4) * scaleFract) >> kShift, 8));
|
||||
|
||||
/* Packing the individual outputs into 32bit and storing in
|
||||
* destination buffer in single write */
|
||||
*__SIMD32(pDst)++ = __PACKq7(out1, out2, out3, out4);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * scale */
|
||||
/* Scale the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (q7_t) (__SSAT(((*pSrc++) * scaleFract) >> kShift, 8));
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * scale */
|
||||
/* Scale the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (q7_t) (__SSAT((((q15_t) * pSrc++ * scaleFract) >> kShift), 8));
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of scale group
|
||||
*/
|
||||
@@ -0,0 +1,248 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_shift_q15.c
|
||||
*
|
||||
* Description: Shifts the elements of a Q15 vector by a specified number of bits.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup shift
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Shifts the elements of a Q15 vector a specified number of bits.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_shift_q15(
|
||||
q15_t * pSrc,
|
||||
int8_t shiftBits,
|
||||
q15_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
uint8_t sign; /* Sign of shiftBits */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
q15_t in1, in2; /* Temporary variables */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* Getting the sign of shiftBits */
|
||||
sign = (shiftBits & 0x80);
|
||||
|
||||
/* If the shift value is positive then do right shift else left shift */
|
||||
if(sign == 0u)
|
||||
{
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* Read 2 inputs */
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
/* C = A << shiftBits */
|
||||
/* Shift the inputs and then store the results in the destination buffer. */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT(__SSAT((in1 << shiftBits), 16),
|
||||
__SSAT((in2 << shiftBits), 16), 16);
|
||||
|
||||
#else
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT(__SSAT((in2 << shiftBits), 16),
|
||||
__SSAT((in1 << shiftBits), 16), 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT(__SSAT((in1 << shiftBits), 16),
|
||||
__SSAT((in2 << shiftBits), 16), 16);
|
||||
|
||||
#else
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT(__SSAT((in2 << shiftBits), 16),
|
||||
__SSAT((in1 << shiftBits), 16), 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A << shiftBits */
|
||||
/* Shift and then store the results in the destination buffer. */
|
||||
*pDst++ = __SSAT((*pSrc++ << shiftBits), 16);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* Read 2 inputs */
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
|
||||
/* C = A >> shiftBits */
|
||||
/* Shift the inputs and then store the results in the destination buffer. */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT((in1 >> -shiftBits),
|
||||
(in2 >> -shiftBits), 16);
|
||||
|
||||
#else
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT((in2 >> -shiftBits),
|
||||
(in1 >> -shiftBits), 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT((in1 >> -shiftBits),
|
||||
(in2 >> -shiftBits), 16);
|
||||
|
||||
#else
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT((in2 >> -shiftBits),
|
||||
(in1 >> -shiftBits), 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A >> shiftBits */
|
||||
/* Shift the inputs and then store the results in the destination buffer. */
|
||||
*pDst++ = (*pSrc++ >> -shiftBits);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Getting the sign of shiftBits */
|
||||
sign = (shiftBits & 0x80);
|
||||
|
||||
/* If the shift value is positive then do right shift else left shift */
|
||||
if(sign == 0u)
|
||||
{
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A << shiftBits */
|
||||
/* Shift and then store the results in the destination buffer. */
|
||||
*pDst++ = __SSAT(((q31_t) * pSrc++ << shiftBits), 16);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A >> shiftBits */
|
||||
/* Shift the inputs and then store the results in the destination buffer. */
|
||||
*pDst++ = (*pSrc++ >> -shiftBits);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of shift group
|
||||
*/
|
||||
@@ -0,0 +1,203 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_shift_q31.c
|
||||
*
|
||||
* Description: Shifts the elements of a Q31 vector by a specified number of bits.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
/**
|
||||
* @defgroup shift Vector Shift
|
||||
*
|
||||
* Shifts the elements of a fixed-point vector by a specified number of bits.
|
||||
* There are separate functions for Q7, Q15, and Q31 data types.
|
||||
* The underlying algorithm used is:
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = pSrc[n] << shift, 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* If <code>shift</code> is positive then the elements of the vector are shifted to the left.
|
||||
* If <code>shift</code> is negative then the elements of the vector are shifted to the right.
|
||||
*
|
||||
* The functions support in-place computation allowing the source and destination
|
||||
* pointers to reference the same memory buffer.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup shift
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Shifts the elements of a Q31 vector a specified number of bits.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_shift_q31(
|
||||
q31_t * pSrc,
|
||||
int8_t shiftBits,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
uint8_t sign = (shiftBits & 0x80); /* Sign of shiftBits */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
q31_t in1, in2, in3, in4; /* Temporary input variables */
|
||||
q31_t out1, out2, out3, out4; /* Temporary output variables */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
|
||||
if(sign == 0u)
|
||||
{
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A << shiftBits */
|
||||
/* Shift the input and then store the results in the destination buffer. */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
out1 = in1 << shiftBits;
|
||||
in3 = *(pSrc + 2);
|
||||
out2 = in2 << shiftBits;
|
||||
in4 = *(pSrc + 3);
|
||||
if(in1 != (out1 >> shiftBits))
|
||||
out1 = 0x7FFFFFFF ^ (in1 >> 31);
|
||||
|
||||
if(in2 != (out2 >> shiftBits))
|
||||
out2 = 0x7FFFFFFF ^ (in2 >> 31);
|
||||
|
||||
*pDst = out1;
|
||||
out3 = in3 << shiftBits;
|
||||
*(pDst + 1) = out2;
|
||||
out4 = in4 << shiftBits;
|
||||
|
||||
if(in3 != (out3 >> shiftBits))
|
||||
out3 = 0x7FFFFFFF ^ (in3 >> 31);
|
||||
|
||||
if(in4 != (out4 >> shiftBits))
|
||||
out4 = 0x7FFFFFFF ^ (in4 >> 31);
|
||||
|
||||
*(pDst + 2) = out3;
|
||||
*(pDst + 3) = out4;
|
||||
|
||||
/* Update destination pointer to process next sampels */
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A >> shiftBits */
|
||||
/* Shift the input and then store the results in the destination buffer. */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
in3 = *(pSrc + 2);
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
*pDst = (in1 >> -shiftBits);
|
||||
*(pDst + 1) = (in2 >> -shiftBits);
|
||||
*(pDst + 2) = (in3 >> -shiftBits);
|
||||
*(pDst + 3) = (in4 >> -shiftBits);
|
||||
|
||||
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A (>> or <<) shiftBits */
|
||||
/* Shift the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (sign == 0u) ? clip_q63_to_q31((q63_t) * pSrc++ << shiftBits) :
|
||||
(*pSrc++ >> -shiftBits);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of shift group
|
||||
*/
|
||||
@@ -0,0 +1,220 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_shift_q7.c
|
||||
*
|
||||
* Description: Processing function for the Q7 Shifting
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup shift
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Shifts the elements of a Q7 vector a specified number of bits.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* \par Conditions for optimum performance
|
||||
* Input and output buffers should be aligned by 32-bit
|
||||
*
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q7 range [0x8 0x7F] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_shift_q7(
|
||||
q7_t * pSrc,
|
||||
int8_t shiftBits,
|
||||
q7_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
uint8_t sign; /* Sign of shiftBits */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q7_t in1; /* Input value1 */
|
||||
q7_t in2; /* Input value2 */
|
||||
q7_t in3; /* Input value3 */
|
||||
q7_t in4; /* Input value4 */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* Getting the sign of shiftBits */
|
||||
sign = (shiftBits & 0x80);
|
||||
|
||||
/* If the shift value is positive then do right shift else left shift */
|
||||
if(sign == 0u)
|
||||
{
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A << shiftBits */
|
||||
/* Read 4 inputs */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
in3 = *(pSrc + 2);
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
/* Store the Shifted result in the destination buffer in single cycle by packing the outputs */
|
||||
*__SIMD32(pDst)++ = __PACKq7(__SSAT((in1 << shiftBits), 8),
|
||||
__SSAT((in2 << shiftBits), 8),
|
||||
__SSAT((in3 << shiftBits), 8),
|
||||
__SSAT((in4 << shiftBits), 8));
|
||||
/* Update source pointer to process next sampels */
|
||||
pSrc += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A << shiftBits */
|
||||
/* Shift the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (q7_t) __SSAT((*pSrc++ << shiftBits), 8);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shiftBits = -shiftBits;
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A >> shiftBits */
|
||||
/* Read 4 inputs */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
in3 = *(pSrc + 2);
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
/* Store the Shifted result in the destination buffer in single cycle by packing the outputs */
|
||||
*__SIMD32(pDst)++ = __PACKq7((in1 >> shiftBits), (in2 >> shiftBits),
|
||||
(in3 >> shiftBits), (in4 >> shiftBits));
|
||||
|
||||
|
||||
pSrc += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A >> shiftBits */
|
||||
/* Shift the input and then store the result in the destination buffer. */
|
||||
in1 = *pSrc++;
|
||||
*pDst++ = (in1 >> shiftBits);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Getting the sign of shiftBits */
|
||||
sign = (shiftBits & 0x80);
|
||||
|
||||
/* If the shift value is positive then do right shift else left shift */
|
||||
if(sign == 0u)
|
||||
{
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A << shiftBits */
|
||||
/* Shift the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (q7_t) __SSAT(((q15_t) * pSrc++ << shiftBits), 8);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A >> shiftBits */
|
||||
/* Shift the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (*pSrc++ >> -shiftBits);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of shift group
|
||||
*/
|
||||
@@ -0,0 +1,150 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_sub_f32.c
|
||||
*
|
||||
* Description: Floating-point vector subtraction.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup BasicSub Vector Subtraction
|
||||
*
|
||||
* Element-by-element subtraction of two vectors.
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = pSrcA[n] - pSrcB[n], 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* There are separate functions for floating-point, Q7, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicSub
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Floating-point vector subtraction.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
void arm_sub_f32(
|
||||
float32_t * pSrcA,
|
||||
float32_t * pSrcB,
|
||||
float32_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
float32_t inA1, inA2, inA3, inA4; /* temporary variables */
|
||||
float32_t inB1, inB2, inB3, inB4; /* temporary variables */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the results in the destination buffer. */
|
||||
/* Read 4 input samples from sourceA and sourceB */
|
||||
inA1 = *pSrcA;
|
||||
inB1 = *pSrcB;
|
||||
inA2 = *(pSrcA + 1);
|
||||
inB2 = *(pSrcB + 1);
|
||||
inA3 = *(pSrcA + 2);
|
||||
inB3 = *(pSrcB + 2);
|
||||
inA4 = *(pSrcA + 3);
|
||||
inB4 = *(pSrcB + 3);
|
||||
|
||||
/* dst = srcA - srcB */
|
||||
/* subtract and store the result */
|
||||
*pDst = inA1 - inB1;
|
||||
*(pDst + 1) = inA2 - inB2;
|
||||
*(pDst + 2) = inA3 - inB3;
|
||||
*(pDst + 3) = inA4 - inB4;
|
||||
|
||||
|
||||
/* Update pointers to process next sampels */
|
||||
pSrcA += 4u;
|
||||
pSrcB += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the results in the destination buffer. */
|
||||
*pDst++ = (*pSrcA++) - (*pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicSub group
|
||||
*/
|
||||
@@ -0,0 +1,140 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_sub_q15.c
|
||||
*
|
||||
* Description: Q15 vector subtraction.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicSub
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q15 vector subtraction.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_sub_q15(
|
||||
q15_t * pSrcA,
|
||||
q15_t * pSrcB,
|
||||
q15_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t inA1, inA2;
|
||||
q31_t inB1, inB2;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the results in the destination buffer two samples at a time. */
|
||||
inA1 = *__SIMD32(pSrcA)++;
|
||||
inA2 = *__SIMD32(pSrcA)++;
|
||||
inB1 = *__SIMD32(pSrcB)++;
|
||||
inB2 = *__SIMD32(pSrcB)++;
|
||||
|
||||
*__SIMD32(pDst)++ = __QSUB16(inA1, inB1);
|
||||
*__SIMD32(pDst)++ = __QSUB16(inA2, inB2);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the result in the destination buffer. */
|
||||
*pDst++ = (q15_t) __QSUB16(*pSrcA++, *pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the result in the destination buffer. */
|
||||
*pDst++ = (q15_t) __SSAT(((q31_t) * pSrcA++ - *pSrcB++), 16);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicSub group
|
||||
*/
|
||||
@@ -0,0 +1,146 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_sub_q31.c
|
||||
*
|
||||
* Description: Q31 vector subtraction.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicSub
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q31 vector subtraction.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_sub_q31(
|
||||
q31_t * pSrcA,
|
||||
q31_t * pSrcB,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t inA1, inA2, inA3, inA4;
|
||||
q31_t inB1, inB2, inB3, inB4;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the results in the destination buffer. */
|
||||
inA1 = *pSrcA++;
|
||||
inA2 = *pSrcA++;
|
||||
inB1 = *pSrcB++;
|
||||
inB2 = *pSrcB++;
|
||||
|
||||
inA3 = *pSrcA++;
|
||||
inA4 = *pSrcA++;
|
||||
inB3 = *pSrcB++;
|
||||
inB4 = *pSrcB++;
|
||||
|
||||
*pDst++ = __QSUB(inA1, inB1);
|
||||
*pDst++ = __QSUB(inA2, inB2);
|
||||
*pDst++ = __QSUB(inA3, inB3);
|
||||
*pDst++ = __QSUB(inA4, inB4);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the result in the destination buffer. */
|
||||
*pDst++ = __QSUB(*pSrcA++, *pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the result in the destination buffer. */
|
||||
*pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrcA++ - *pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicSub group
|
||||
*/
|
||||
@@ -0,0 +1,131 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_sub_q7.c
|
||||
*
|
||||
* Description: Q7 vector subtraction.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicSub
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q7 vector subtraction.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q7 range [0x80 0x7F] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_sub_q7(
|
||||
q7_t * pSrcA,
|
||||
q7_t * pSrcB,
|
||||
q7_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the results in the destination buffer 4 samples at a time. */
|
||||
*__SIMD32(pDst)++ = __QSUB8(*__SIMD32(pSrcA)++, *__SIMD32(pSrcB)++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the result in the destination buffer. */
|
||||
*pDst++ = __SSAT(*pSrcA++ - *pSrcB++, 8);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the result in the destination buffer. */
|
||||
*pDst++ = (q7_t) __SSAT((q15_t) * pSrcA++ - *pSrcB++, 8);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicSub group
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,156 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_const_structs.c
|
||||
*
|
||||
* Description: This file has constant structs that are initialized for
|
||||
* user convenience. For example, some can be given as
|
||||
* arguments to the arm_cfft_f32() function.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_const_structs.h"
|
||||
|
||||
//Floating-point structs
|
||||
|
||||
const arm_cfft_instance_f32 arm_cfft_sR_f32_len16 = {
|
||||
16, twiddleCoef_16, armBitRevIndexTable16, ARMBITREVINDEXTABLE__16_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_f32 arm_cfft_sR_f32_len32 = {
|
||||
32, twiddleCoef_32, armBitRevIndexTable32, ARMBITREVINDEXTABLE__32_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_f32 arm_cfft_sR_f32_len64 = {
|
||||
64, twiddleCoef_64, armBitRevIndexTable64, ARMBITREVINDEXTABLE__64_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_f32 arm_cfft_sR_f32_len128 = {
|
||||
128, twiddleCoef_128, armBitRevIndexTable128, ARMBITREVINDEXTABLE_128_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_f32 arm_cfft_sR_f32_len256 = {
|
||||
256, twiddleCoef_256, armBitRevIndexTable256, ARMBITREVINDEXTABLE_256_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_f32 arm_cfft_sR_f32_len512 = {
|
||||
512, twiddleCoef_512, armBitRevIndexTable512, ARMBITREVINDEXTABLE_512_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024 = {
|
||||
1024, twiddleCoef_1024, armBitRevIndexTable1024, ARMBITREVINDEXTABLE1024_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048 = {
|
||||
2048, twiddleCoef_2048, armBitRevIndexTable2048, ARMBITREVINDEXTABLE2048_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096 = {
|
||||
4096, twiddleCoef_4096, armBitRevIndexTable4096, ARMBITREVINDEXTABLE4096_TABLE_LENGTH
|
||||
};
|
||||
|
||||
//Fixed-point structs
|
||||
|
||||
const arm_cfft_instance_q31 arm_cfft_sR_q31_len16 = {
|
||||
16, twiddleCoef_16_q31, armBitRevIndexTable_fixed_16, ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_q31 arm_cfft_sR_q31_len32 = {
|
||||
32, twiddleCoef_32_q31, armBitRevIndexTable_fixed_32, ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_q31 arm_cfft_sR_q31_len64 = {
|
||||
64, twiddleCoef_64_q31, armBitRevIndexTable_fixed_64, ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_q31 arm_cfft_sR_q31_len128 = {
|
||||
128, twiddleCoef_128_q31, armBitRevIndexTable_fixed_128, ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_q31 arm_cfft_sR_q31_len256 = {
|
||||
256, twiddleCoef_256_q31, armBitRevIndexTable_fixed_256, ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_q31 arm_cfft_sR_q31_len512 = {
|
||||
512, twiddleCoef_512_q31, armBitRevIndexTable_fixed_512, ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024 = {
|
||||
1024, twiddleCoef_1024_q31, armBitRevIndexTable_fixed_1024, ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048 = {
|
||||
2048, twiddleCoef_2048_q31, armBitRevIndexTable_fixed_2048, ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096 = {
|
||||
4096, twiddleCoef_4096_q31, armBitRevIndexTable_fixed_4096, ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH
|
||||
};
|
||||
|
||||
|
||||
const arm_cfft_instance_q15 arm_cfft_sR_q15_len16 = {
|
||||
16, twiddleCoef_16_q15, armBitRevIndexTable_fixed_16, ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_q15 arm_cfft_sR_q15_len32 = {
|
||||
32, twiddleCoef_32_q15, armBitRevIndexTable_fixed_32, ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_q15 arm_cfft_sR_q15_len64 = {
|
||||
64, twiddleCoef_64_q15, armBitRevIndexTable_fixed_64, ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_q15 arm_cfft_sR_q15_len128 = {
|
||||
128, twiddleCoef_128_q15, armBitRevIndexTable_fixed_128, ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_q15 arm_cfft_sR_q15_len256 = {
|
||||
256, twiddleCoef_256_q15, armBitRevIndexTable_fixed_256, ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_q15 arm_cfft_sR_q15_len512 = {
|
||||
512, twiddleCoef_512_q15, armBitRevIndexTable_fixed_512, ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024 = {
|
||||
1024, twiddleCoef_1024_q15, armBitRevIndexTable_fixed_1024, ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048 = {
|
||||
2048, twiddleCoef_2048_q15, armBitRevIndexTable_fixed_2048, ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH
|
||||
};
|
||||
|
||||
const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096 = {
|
||||
4096, twiddleCoef_4096_q15, armBitRevIndexTable_fixed_4096, ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH
|
||||
};
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_conj_f32.c
|
||||
*
|
||||
* Description: Floating-point complex conjugate.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------- */
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup cmplx_conj Complex Conjugate
|
||||
*
|
||||
* Conjugates the elements of a complex data vector.
|
||||
*
|
||||
* The <code>pSrc</code> points to the source data and
|
||||
* <code>pDst</code> points to the where the result should be written.
|
||||
* <code>numSamples</code> specifies the number of complex samples
|
||||
* and the data in each array is stored in an interleaved fashion
|
||||
* (real, imag, real, imag, ...).
|
||||
* Each array has a total of <code>2*numSamples</code> values.
|
||||
* The underlying algorithm is used:
|
||||
*
|
||||
* <pre>
|
||||
* for(n=0; n<numSamples; n++) {
|
||||
* pDst[(2*n)+0)] = pSrc[(2*n)+0]; // real part
|
||||
* pDst[(2*n)+1)] = -pSrc[(2*n)+1]; // imag part
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* There are separate functions for floating-point, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup cmplx_conj
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Floating-point complex conjugate.
|
||||
* @param *pSrc points to the input vector
|
||||
* @param *pDst points to the output vector
|
||||
* @param numSamples number of complex samples in each vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
void arm_cmplx_conj_f32(
|
||||
float32_t * pSrc,
|
||||
float32_t * pDst,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
float32_t inR1, inR2, inR3, inR4;
|
||||
float32_t inI1, inI2, inI3, inI4;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[0]+jC[1] = A[0]+ j (-1) A[1] */
|
||||
/* Calculate Complex Conjugate and then store the results in the destination buffer. */
|
||||
/* read real input samples */
|
||||
inR1 = pSrc[0];
|
||||
/* store real samples to destination */
|
||||
pDst[0] = inR1;
|
||||
inR2 = pSrc[2];
|
||||
pDst[2] = inR2;
|
||||
inR3 = pSrc[4];
|
||||
pDst[4] = inR3;
|
||||
inR4 = pSrc[6];
|
||||
pDst[6] = inR4;
|
||||
|
||||
/* read imaginary input samples */
|
||||
inI1 = pSrc[1];
|
||||
inI2 = pSrc[3];
|
||||
|
||||
/* conjugate input */
|
||||
inI1 = -inI1;
|
||||
|
||||
/* read imaginary input samples */
|
||||
inI3 = pSrc[5];
|
||||
|
||||
/* conjugate input */
|
||||
inI2 = -inI2;
|
||||
|
||||
/* read imaginary input samples */
|
||||
inI4 = pSrc[7];
|
||||
|
||||
/* conjugate input */
|
||||
inI3 = -inI3;
|
||||
|
||||
/* store imaginary samples to destination */
|
||||
pDst[1] = inI1;
|
||||
pDst[3] = inI2;
|
||||
|
||||
/* conjugate input */
|
||||
inI4 = -inI4;
|
||||
|
||||
/* store imaginary samples to destination */
|
||||
pDst[5] = inI3;
|
||||
|
||||
/* increment source pointer by 8 to process next sampels */
|
||||
pSrc += 8u;
|
||||
|
||||
/* store imaginary sample to destination */
|
||||
pDst[7] = inI4;
|
||||
|
||||
/* increment destination pointer by 8 to store next samples */
|
||||
pDst += 8u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
blkCnt = numSamples;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* realOut + j (imagOut) = realIn + j (-1) imagIn */
|
||||
/* Calculate Complex Conjugate and then store the results in the destination buffer. */
|
||||
*pDst++ = *pSrc++;
|
||||
*pDst++ = -*pSrc++;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of cmplx_conj group
|
||||
*/
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. October 2015
|
||||
* $Revision: V.1.4.5 a
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_conj_q15.c
|
||||
*
|
||||
* Description: Q15 complex conjugate.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup cmplx_conj
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q15 complex conjugate.
|
||||
* @param *pSrc points to the input vector
|
||||
* @param *pDst points to the output vector
|
||||
* @param numSamples number of complex samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* The Q15 value -1 (0x8000) will be saturated to the maximum allowable positive value 0x7FFF.
|
||||
*/
|
||||
|
||||
void arm_cmplx_conj_q15(
|
||||
q15_t * pSrc,
|
||||
q15_t * pDst,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
q31_t in1, in2, in3, in4;
|
||||
q31_t zero = 0;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[0]+jC[1] = A[0]+ j (-1) A[1] */
|
||||
/* Calculate Complex Conjugate and then store the results in the destination buffer. */
|
||||
in1 = *__SIMD32(pSrc)++;
|
||||
in2 = *__SIMD32(pSrc)++;
|
||||
in3 = *__SIMD32(pSrc)++;
|
||||
in4 = *__SIMD32(pSrc)++;
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
in1 = __QASX(zero, in1);
|
||||
in2 = __QASX(zero, in2);
|
||||
in3 = __QASX(zero, in3);
|
||||
in4 = __QASX(zero, in4);
|
||||
|
||||
#else
|
||||
|
||||
in1 = __QSAX(zero, in1);
|
||||
in2 = __QSAX(zero, in2);
|
||||
in3 = __QSAX(zero, in3);
|
||||
in4 = __QSAX(zero, in4);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
in1 = ((uint32_t) in1 >> 16) | ((uint32_t) in1 << 16);
|
||||
in2 = ((uint32_t) in2 >> 16) | ((uint32_t) in2 << 16);
|
||||
in3 = ((uint32_t) in3 >> 16) | ((uint32_t) in3 << 16);
|
||||
in4 = ((uint32_t) in4 >> 16) | ((uint32_t) in4 << 16);
|
||||
|
||||
*__SIMD32(pDst)++ = in1;
|
||||
*__SIMD32(pDst)++ = in2;
|
||||
*__SIMD32(pDst)++ = in3;
|
||||
*__SIMD32(pDst)++ = in4;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[0]+jC[1] = A[0]+ j (-1) A[1] */
|
||||
/* Calculate Complex Conjugate and then store the results in the destination buffer. */
|
||||
*pDst++ = *pSrc++;
|
||||
*pDst++ = __SSAT(-*pSrc++, 16);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
q15_t in;
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
while(numSamples > 0u)
|
||||
{
|
||||
/* realOut + j (imagOut) = realIn+ j (-1) imagIn */
|
||||
/* Calculate Complex Conjugate and then store the results in the destination buffer. */
|
||||
*pDst++ = *pSrc++;
|
||||
in = *pSrc++;
|
||||
*pDst++ = (in == (q15_t) 0x8000) ? 0x7fff : -in;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
numSamples--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of cmplx_conj group
|
||||
*/
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_conj_q31.c
|
||||
*
|
||||
* Description: Q31 complex conjugate.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------- */
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup cmplx_conj
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q31 complex conjugate.
|
||||
* @param *pSrc points to the input vector
|
||||
* @param *pDst points to the output vector
|
||||
* @param numSamples number of complex samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* The Q31 value -1 (0x80000000) will be saturated to the maximum allowable positive value 0x7FFFFFFF.
|
||||
*/
|
||||
|
||||
void arm_cmplx_conj_q31(
|
||||
q31_t * pSrc,
|
||||
q31_t * pDst,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
q31_t in; /* Input value */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t inR1, inR2, inR3, inR4; /* Temporary real variables */
|
||||
q31_t inI1, inI2, inI3, inI4; /* Temporary imaginary variables */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[0]+jC[1] = A[0]+ j (-1) A[1] */
|
||||
/* Calculate Complex Conjugate and then store the results in the destination buffer. */
|
||||
/* Saturated to 0x7fffffff if the input is -1(0x80000000) */
|
||||
/* read real input sample */
|
||||
inR1 = pSrc[0];
|
||||
/* store real input sample */
|
||||
pDst[0] = inR1;
|
||||
|
||||
/* read imaginary input sample */
|
||||
inI1 = pSrc[1];
|
||||
|
||||
/* read real input sample */
|
||||
inR2 = pSrc[2];
|
||||
/* store real input sample */
|
||||
pDst[2] = inR2;
|
||||
|
||||
/* read imaginary input sample */
|
||||
inI2 = pSrc[3];
|
||||
|
||||
/* negate imaginary input sample */
|
||||
inI1 = __QSUB(0, inI1);
|
||||
|
||||
/* read real input sample */
|
||||
inR3 = pSrc[4];
|
||||
/* store real input sample */
|
||||
pDst[4] = inR3;
|
||||
|
||||
/* read imaginary input sample */
|
||||
inI3 = pSrc[5];
|
||||
|
||||
/* negate imaginary input sample */
|
||||
inI2 = __QSUB(0, inI2);
|
||||
|
||||
/* read real input sample */
|
||||
inR4 = pSrc[6];
|
||||
/* store real input sample */
|
||||
pDst[6] = inR4;
|
||||
|
||||
/* negate imaginary input sample */
|
||||
inI3 = __QSUB(0, inI3);
|
||||
|
||||
/* store imaginary input sample */
|
||||
inI4 = pSrc[7];
|
||||
|
||||
/* store imaginary input samples */
|
||||
pDst[1] = inI1;
|
||||
|
||||
/* negate imaginary input sample */
|
||||
inI4 = __QSUB(0, inI4);
|
||||
|
||||
/* store imaginary input samples */
|
||||
pDst[3] = inI2;
|
||||
|
||||
/* increment source pointer by 8 to proecess next samples */
|
||||
pSrc += 8u;
|
||||
|
||||
/* store imaginary input samples */
|
||||
pDst[5] = inI3;
|
||||
pDst[7] = inI4;
|
||||
|
||||
/* increment destination pointer by 8 to process next samples */
|
||||
pDst += 8u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
blkCnt = numSamples;
|
||||
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[0]+jC[1] = A[0]+ j (-1) A[1] */
|
||||
/* Calculate Complex Conjugate and then store the results in the destination buffer. */
|
||||
/* Saturated to 0x7fffffff if the input is -1(0x80000000) */
|
||||
*pDst++ = *pSrc++;
|
||||
in = *pSrc++;
|
||||
*pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of cmplx_conj group
|
||||
*/
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_dot_prod_f32.c
|
||||
*
|
||||
* Description: Floating-point complex dot product
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup cmplx_dot_prod Complex Dot Product
|
||||
*
|
||||
* Computes the dot product of two complex vectors.
|
||||
* The vectors are multiplied element-by-element and then summed.
|
||||
*
|
||||
* The <code>pSrcA</code> points to the first complex input vector and
|
||||
* <code>pSrcB</code> points to the second complex input vector.
|
||||
* <code>numSamples</code> specifies the number of complex samples
|
||||
* and the data in each array is stored in an interleaved fashion
|
||||
* (real, imag, real, imag, ...).
|
||||
* Each array has a total of <code>2*numSamples</code> values.
|
||||
*
|
||||
* The underlying algorithm is used:
|
||||
* <pre>
|
||||
* realResult=0;
|
||||
* imagResult=0;
|
||||
* for(n=0; n<numSamples; n++) {
|
||||
* realResult += pSrcA[(2*n)+0]*pSrcB[(2*n)+0] - pSrcA[(2*n)+1]*pSrcB[(2*n)+1];
|
||||
* imagResult += pSrcA[(2*n)+0]*pSrcB[(2*n)+1] + pSrcA[(2*n)+1]*pSrcB[(2*n)+0];
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* There are separate functions for floating-point, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup cmplx_dot_prod
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Floating-point complex dot product
|
||||
* @param *pSrcA points to the first input vector
|
||||
* @param *pSrcB points to the second input vector
|
||||
* @param numSamples number of complex samples in each vector
|
||||
* @param *realResult real part of the result returned here
|
||||
* @param *imagResult imaginary part of the result returned here
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
void arm_cmplx_dot_prod_f32(
|
||||
float32_t * pSrcA,
|
||||
float32_t * pSrcB,
|
||||
uint32_t numSamples,
|
||||
float32_t * realResult,
|
||||
float32_t * imagResult)
|
||||
{
|
||||
float32_t real_sum = 0.0f, imag_sum = 0.0f; /* Temporary result storage */
|
||||
float32_t a0,b0,c0,d0;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += a0 * c0;
|
||||
imag_sum += a0 * d0;
|
||||
real_sum -= b0 * d0;
|
||||
imag_sum += b0 * c0;
|
||||
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += a0 * c0;
|
||||
imag_sum += a0 * d0;
|
||||
real_sum -= b0 * d0;
|
||||
imag_sum += b0 * c0;
|
||||
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += a0 * c0;
|
||||
imag_sum += a0 * d0;
|
||||
real_sum -= b0 * d0;
|
||||
imag_sum += b0 * c0;
|
||||
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += a0 * c0;
|
||||
imag_sum += a0 * d0;
|
||||
real_sum -= b0 * d0;
|
||||
imag_sum += b0 * c0;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples & 0x3u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += a0 * c0;
|
||||
imag_sum += a0 * d0;
|
||||
real_sum -= b0 * d0;
|
||||
imag_sum += b0 * c0;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
while(numSamples > 0u)
|
||||
{
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += a0 * c0;
|
||||
imag_sum += a0 * d0;
|
||||
real_sum -= b0 * d0;
|
||||
imag_sum += b0 * c0;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
numSamples--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
/* Store the real and imaginary results in the destination buffers */
|
||||
*realResult = real_sum;
|
||||
*imagResult = imag_sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of cmplx_dot_prod group
|
||||
*/
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_dot_prod_q15.c
|
||||
*
|
||||
* Description: Processing function for the Q15 Complex Dot product
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup cmplx_dot_prod
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q15 complex dot product
|
||||
* @param *pSrcA points to the first input vector
|
||||
* @param *pSrcB points to the second input vector
|
||||
* @param numSamples number of complex samples in each vector
|
||||
* @param *realResult real part of the result returned here
|
||||
* @param *imagResult imaginary part of the result returned here
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function is implemented using an internal 64-bit accumulator.
|
||||
* The intermediate 1.15 by 1.15 multiplications are performed with full precision and yield a 2.30 result.
|
||||
* These are accumulated in a 64-bit accumulator with 34.30 precision.
|
||||
* As a final step, the accumulators are converted to 8.24 format.
|
||||
* The return results <code>realResult</code> and <code>imagResult</code> are in 8.24 format.
|
||||
*/
|
||||
|
||||
void arm_cmplx_dot_prod_q15(
|
||||
q15_t * pSrcA,
|
||||
q15_t * pSrcB,
|
||||
uint32_t numSamples,
|
||||
q31_t * realResult,
|
||||
q31_t * imagResult)
|
||||
{
|
||||
q63_t real_sum = 0, imag_sum = 0; /* Temporary result storage */
|
||||
q15_t a0,b0,c0,d0;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += (q31_t)a0 * c0;
|
||||
imag_sum += (q31_t)a0 * d0;
|
||||
real_sum -= (q31_t)b0 * d0;
|
||||
imag_sum += (q31_t)b0 * c0;
|
||||
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += (q31_t)a0 * c0;
|
||||
imag_sum += (q31_t)a0 * d0;
|
||||
real_sum -= (q31_t)b0 * d0;
|
||||
imag_sum += (q31_t)b0 * c0;
|
||||
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += (q31_t)a0 * c0;
|
||||
imag_sum += (q31_t)a0 * d0;
|
||||
real_sum -= (q31_t)b0 * d0;
|
||||
imag_sum += (q31_t)b0 * c0;
|
||||
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += (q31_t)a0 * c0;
|
||||
imag_sum += (q31_t)a0 * d0;
|
||||
real_sum -= (q31_t)b0 * d0;
|
||||
imag_sum += (q31_t)b0 * c0;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += (q31_t)a0 * c0;
|
||||
imag_sum += (q31_t)a0 * d0;
|
||||
real_sum -= (q31_t)b0 * d0;
|
||||
imag_sum += (q31_t)b0 * c0;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
while(numSamples > 0u)
|
||||
{
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += a0 * c0;
|
||||
imag_sum += a0 * d0;
|
||||
real_sum -= b0 * d0;
|
||||
imag_sum += b0 * c0;
|
||||
|
||||
|
||||
/* Decrement the loop counter */
|
||||
numSamples--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
/* Store the real and imaginary results in 8.24 format */
|
||||
/* Convert real data in 34.30 to 8.24 by 6 right shifts */
|
||||
*realResult = (q31_t) (real_sum >> 6);
|
||||
/* Convert imaginary data in 34.30 to 8.24 by 6 right shifts */
|
||||
*imagResult = (q31_t) (imag_sum >> 6);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of cmplx_dot_prod group
|
||||
*/
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_dot_prod_q31.c
|
||||
*
|
||||
* Description: Q31 complex dot product
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup cmplx_dot_prod
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q31 complex dot product
|
||||
* @param *pSrcA points to the first input vector
|
||||
* @param *pSrcB points to the second input vector
|
||||
* @param numSamples number of complex samples in each vector
|
||||
* @param *realResult real part of the result returned here
|
||||
* @param *imagResult imaginary part of the result returned here
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function is implemented using an internal 64-bit accumulator.
|
||||
* The intermediate 1.31 by 1.31 multiplications are performed with 64-bit precision and then shifted to 16.48 format.
|
||||
* The internal real and imaginary accumulators are in 16.48 format and provide 15 guard bits.
|
||||
* Additions are nonsaturating and no overflow will occur as long as <code>numSamples</code> is less than 32768.
|
||||
* The return results <code>realResult</code> and <code>imagResult</code> are in 16.48 format.
|
||||
* Input down scaling is not required.
|
||||
*/
|
||||
|
||||
void arm_cmplx_dot_prod_q31(
|
||||
q31_t * pSrcA,
|
||||
q31_t * pSrcB,
|
||||
uint32_t numSamples,
|
||||
q63_t * realResult,
|
||||
q63_t * imagResult)
|
||||
{
|
||||
q63_t real_sum = 0, imag_sum = 0; /* Temporary result storage */
|
||||
q31_t a0,b0,c0,d0;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += ((q63_t)a0 * c0) >> 14;
|
||||
imag_sum += ((q63_t)a0 * d0) >> 14;
|
||||
real_sum -= ((q63_t)b0 * d0) >> 14;
|
||||
imag_sum += ((q63_t)b0 * c0) >> 14;
|
||||
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += ((q63_t)a0 * c0) >> 14;
|
||||
imag_sum += ((q63_t)a0 * d0) >> 14;
|
||||
real_sum -= ((q63_t)b0 * d0) >> 14;
|
||||
imag_sum += ((q63_t)b0 * c0) >> 14;
|
||||
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += ((q63_t)a0 * c0) >> 14;
|
||||
imag_sum += ((q63_t)a0 * d0) >> 14;
|
||||
real_sum -= ((q63_t)b0 * d0) >> 14;
|
||||
imag_sum += ((q63_t)b0 * c0) >> 14;
|
||||
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += ((q63_t)a0 * c0) >> 14;
|
||||
imag_sum += ((q63_t)a0 * d0) >> 14;
|
||||
real_sum -= ((q63_t)b0 * d0) >> 14;
|
||||
imag_sum += ((q63_t)b0 * c0) >> 14;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += ((q63_t)a0 * c0) >> 14;
|
||||
imag_sum += ((q63_t)a0 * d0) >> 14;
|
||||
real_sum -= ((q63_t)b0 * d0) >> 14;
|
||||
imag_sum += ((q63_t)b0 * c0) >> 14;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
while(numSamples > 0u)
|
||||
{
|
||||
a0 = *pSrcA++;
|
||||
b0 = *pSrcA++;
|
||||
c0 = *pSrcB++;
|
||||
d0 = *pSrcB++;
|
||||
|
||||
real_sum += ((q63_t)a0 * c0) >> 14;
|
||||
imag_sum += ((q63_t)a0 * d0) >> 14;
|
||||
real_sum -= ((q63_t)b0 * d0) >> 14;
|
||||
imag_sum += ((q63_t)b0 * c0) >> 14;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
numSamples--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
/* Store the real and imaginary results in 16.48 format */
|
||||
*realResult = real_sum;
|
||||
*imagResult = imag_sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of cmplx_dot_prod group
|
||||
*/
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_mag_f32.c
|
||||
*
|
||||
* Description: Floating-point complex magnitude.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup cmplx_mag Complex Magnitude
|
||||
*
|
||||
* Computes the magnitude of the elements of a complex data vector.
|
||||
*
|
||||
* The <code>pSrc</code> points to the source data and
|
||||
* <code>pDst</code> points to the where the result should be written.
|
||||
* <code>numSamples</code> specifies the number of complex samples
|
||||
* in the input array and the data is stored in an interleaved fashion
|
||||
* (real, imag, real, imag, ...).
|
||||
* The input array has a total of <code>2*numSamples</code> values;
|
||||
* the output array has a total of <code>numSamples</code> values.
|
||||
* The underlying algorithm is used:
|
||||
*
|
||||
* <pre>
|
||||
* for(n=0; n<numSamples; n++) {
|
||||
* pDst[n] = sqrt(pSrc[(2*n)+0]^2 + pSrc[(2*n)+1]^2);
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* There are separate functions for floating-point, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup cmplx_mag
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Floating-point complex magnitude.
|
||||
* @param[in] *pSrc points to complex input buffer
|
||||
* @param[out] *pDst points to real output buffer
|
||||
* @param[in] numSamples number of complex samples in the input vector
|
||||
* @return none.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
void arm_cmplx_mag_f32(
|
||||
float32_t * pSrc,
|
||||
float32_t * pDst,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
float32_t realIn, imagIn; /* Temporary variables to hold input values */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
|
||||
/* C[0] = sqrt(A[0] * A[0] + A[1] * A[1]) */
|
||||
realIn = *pSrc++;
|
||||
imagIn = *pSrc++;
|
||||
/* store the result in the destination buffer. */
|
||||
arm_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);
|
||||
|
||||
realIn = *pSrc++;
|
||||
imagIn = *pSrc++;
|
||||
arm_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);
|
||||
|
||||
realIn = *pSrc++;
|
||||
imagIn = *pSrc++;
|
||||
arm_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);
|
||||
|
||||
realIn = *pSrc++;
|
||||
imagIn = *pSrc++;
|
||||
arm_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);
|
||||
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[0] = sqrt(A[0] * A[0] + A[1] * A[1]) */
|
||||
realIn = *pSrc++;
|
||||
imagIn = *pSrc++;
|
||||
/* store the result in the destination buffer. */
|
||||
arm_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
while(numSamples > 0u)
|
||||
{
|
||||
/* out = sqrt((real * real) + (imag * imag)) */
|
||||
realIn = *pSrc++;
|
||||
imagIn = *pSrc++;
|
||||
/* store the result in the destination buffer. */
|
||||
arm_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
numSamples--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of cmplx_mag group
|
||||
*/
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_mag_q15.c
|
||||
*
|
||||
* Description: Q15 complex magnitude.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup cmplx_mag
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Q15 complex magnitude
|
||||
* @param *pSrc points to the complex input vector
|
||||
* @param *pDst points to the real output vector
|
||||
* @param numSamples number of complex samples in the input vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function implements 1.15 by 1.15 multiplications and finally output is converted into 2.14 format.
|
||||
*/
|
||||
|
||||
void arm_cmplx_mag_q15(
|
||||
q15_t * pSrc,
|
||||
q15_t * pDst,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
q31_t acc0, acc1; /* Accumulators */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
q31_t in1, in2, in3, in4;
|
||||
q31_t acc2, acc3;
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
|
||||
/* C[0] = sqrt(A[0] * A[0] + A[1] * A[1]) */
|
||||
in1 = *__SIMD32(pSrc)++;
|
||||
in2 = *__SIMD32(pSrc)++;
|
||||
in3 = *__SIMD32(pSrc)++;
|
||||
in4 = *__SIMD32(pSrc)++;
|
||||
|
||||
acc0 = __SMUAD(in1, in1);
|
||||
acc1 = __SMUAD(in2, in2);
|
||||
acc2 = __SMUAD(in3, in3);
|
||||
acc3 = __SMUAD(in4, in4);
|
||||
|
||||
/* store the result in 2.14 format in the destination buffer. */
|
||||
arm_sqrt_q15((q15_t) ((acc0) >> 17), pDst++);
|
||||
arm_sqrt_q15((q15_t) ((acc1) >> 17), pDst++);
|
||||
arm_sqrt_q15((q15_t) ((acc2) >> 17), pDst++);
|
||||
arm_sqrt_q15((q15_t) ((acc3) >> 17), pDst++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[0] = sqrt(A[0] * A[0] + A[1] * A[1]) */
|
||||
in1 = *__SIMD32(pSrc)++;
|
||||
acc0 = __SMUAD(in1, in1);
|
||||
|
||||
/* store the result in 2.14 format in the destination buffer. */
|
||||
arm_sqrt_q15((q15_t) (acc0 >> 17), pDst++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
q15_t real, imag; /* Temporary variables to hold input values */
|
||||
|
||||
while(numSamples > 0u)
|
||||
{
|
||||
/* out = sqrt(real * real + imag * imag) */
|
||||
real = *pSrc++;
|
||||
imag = *pSrc++;
|
||||
|
||||
acc0 = (real * real);
|
||||
acc1 = (imag * imag);
|
||||
|
||||
/* store the result in 2.14 format in the destination buffer. */
|
||||
arm_sqrt_q15((q15_t) (((q63_t) acc0 + acc1) >> 17), pDst++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
numSamples--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of cmplx_mag group
|
||||
*/
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_mag_q31.c
|
||||
*
|
||||
* Description: Q31 complex magnitude
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup cmplx_mag
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q31 complex magnitude
|
||||
* @param *pSrc points to the complex input vector
|
||||
* @param *pDst points to the real output vector
|
||||
* @param numSamples number of complex samples in the input vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function implements 1.31 by 1.31 multiplications and finally output is converted into 2.30 format.
|
||||
* Input down scaling is not required.
|
||||
*/
|
||||
|
||||
void arm_cmplx_mag_q31(
|
||||
q31_t * pSrc,
|
||||
q31_t * pDst,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
q31_t real, imag; /* Temporary variables to hold input values */
|
||||
q31_t acc0, acc1; /* Accumulators */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t real1, real2, imag1, imag2; /* Temporary variables to hold input values */
|
||||
q31_t out1, out2, out3, out4; /* Accumulators */
|
||||
q63_t mul1, mul2, mul3, mul4; /* Temporary variables */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* read complex input from source buffer */
|
||||
real1 = pSrc[0];
|
||||
imag1 = pSrc[1];
|
||||
real2 = pSrc[2];
|
||||
imag2 = pSrc[3];
|
||||
|
||||
/* calculate power of input values */
|
||||
mul1 = (q63_t) real1 *real1;
|
||||
mul2 = (q63_t) imag1 *imag1;
|
||||
mul3 = (q63_t) real2 *real2;
|
||||
mul4 = (q63_t) imag2 *imag2;
|
||||
|
||||
/* get the result to 3.29 format */
|
||||
out1 = (q31_t) (mul1 >> 33);
|
||||
out2 = (q31_t) (mul2 >> 33);
|
||||
out3 = (q31_t) (mul3 >> 33);
|
||||
out4 = (q31_t) (mul4 >> 33);
|
||||
|
||||
/* add real and imaginary accumulators */
|
||||
out1 = out1 + out2;
|
||||
out3 = out3 + out4;
|
||||
|
||||
/* read complex input from source buffer */
|
||||
real1 = pSrc[4];
|
||||
imag1 = pSrc[5];
|
||||
real2 = pSrc[6];
|
||||
imag2 = pSrc[7];
|
||||
|
||||
/* calculate square root */
|
||||
arm_sqrt_q31(out1, &pDst[0]);
|
||||
|
||||
/* calculate power of input values */
|
||||
mul1 = (q63_t) real1 *real1;
|
||||
|
||||
/* calculate square root */
|
||||
arm_sqrt_q31(out3, &pDst[1]);
|
||||
|
||||
/* calculate power of input values */
|
||||
mul2 = (q63_t) imag1 *imag1;
|
||||
mul3 = (q63_t) real2 *real2;
|
||||
mul4 = (q63_t) imag2 *imag2;
|
||||
|
||||
/* get the result to 3.29 format */
|
||||
out1 = (q31_t) (mul1 >> 33);
|
||||
out2 = (q31_t) (mul2 >> 33);
|
||||
out3 = (q31_t) (mul3 >> 33);
|
||||
out4 = (q31_t) (mul4 >> 33);
|
||||
|
||||
/* add real and imaginary accumulators */
|
||||
out1 = out1 + out2;
|
||||
out3 = out3 + out4;
|
||||
|
||||
/* calculate square root */
|
||||
arm_sqrt_q31(out1, &pDst[2]);
|
||||
|
||||
/* increment destination by 8 to process next samples */
|
||||
pSrc += 8u;
|
||||
|
||||
/* calculate square root */
|
||||
arm_sqrt_q31(out3, &pDst[3]);
|
||||
|
||||
/* increment destination by 4 to process next samples */
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
blkCnt = numSamples;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[0] = sqrt(A[0] * A[0] + A[1] * A[1]) */
|
||||
real = *pSrc++;
|
||||
imag = *pSrc++;
|
||||
acc0 = (q31_t) (((q63_t) real * real) >> 33);
|
||||
acc1 = (q31_t) (((q63_t) imag * imag) >> 33);
|
||||
/* store the result in 2.30 format in the destination buffer. */
|
||||
arm_sqrt_q31(acc0 + acc1, pDst++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of cmplx_mag group
|
||||
*/
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_mag_squared_f32.c
|
||||
*
|
||||
* Description: Floating-point complex magnitude squared.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------- */
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup cmplx_mag_squared Complex Magnitude Squared
|
||||
*
|
||||
* Computes the magnitude squared of the elements of a complex data vector.
|
||||
*
|
||||
* The <code>pSrc</code> points to the source data and
|
||||
* <code>pDst</code> points to the where the result should be written.
|
||||
* <code>numSamples</code> specifies the number of complex samples
|
||||
* in the input array and the data is stored in an interleaved fashion
|
||||
* (real, imag, real, imag, ...).
|
||||
* The input array has a total of <code>2*numSamples</code> values;
|
||||
* the output array has a total of <code>numSamples</code> values.
|
||||
*
|
||||
* The underlying algorithm is used:
|
||||
*
|
||||
* <pre>
|
||||
* for(n=0; n<numSamples; n++) {
|
||||
* pDst[n] = pSrc[(2*n)+0]^2 + pSrc[(2*n)+1]^2;
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* There are separate functions for floating-point, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup cmplx_mag_squared
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Floating-point complex magnitude squared
|
||||
* @param[in] *pSrc points to the complex input vector
|
||||
* @param[out] *pDst points to the real output vector
|
||||
* @param[in] numSamples number of complex samples in the input vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
void arm_cmplx_mag_squared_f32(
|
||||
float32_t * pSrc,
|
||||
float32_t * pDst,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
float32_t real, imag; /* Temporary variables to store real and imaginary values */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
float32_t real1, real2, real3, real4; /* Temporary variables to hold real values */
|
||||
float32_t imag1, imag2, imag3, imag4; /* Temporary variables to hold imaginary values */
|
||||
float32_t mul1, mul2, mul3, mul4; /* Temporary variables */
|
||||
float32_t mul5, mul6, mul7, mul8; /* Temporary variables */
|
||||
float32_t out1, out2, out3, out4; /* Temporary variables to hold output values */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[0] = (A[0] * A[0] + A[1] * A[1]) */
|
||||
/* read real input sample from source buffer */
|
||||
real1 = pSrc[0];
|
||||
/* read imaginary input sample from source buffer */
|
||||
imag1 = pSrc[1];
|
||||
|
||||
/* calculate power of real value */
|
||||
mul1 = real1 * real1;
|
||||
|
||||
/* read real input sample from source buffer */
|
||||
real2 = pSrc[2];
|
||||
|
||||
/* calculate power of imaginary value */
|
||||
mul2 = imag1 * imag1;
|
||||
|
||||
/* read imaginary input sample from source buffer */
|
||||
imag2 = pSrc[3];
|
||||
|
||||
/* calculate power of real value */
|
||||
mul3 = real2 * real2;
|
||||
|
||||
/* read real input sample from source buffer */
|
||||
real3 = pSrc[4];
|
||||
|
||||
/* calculate power of imaginary value */
|
||||
mul4 = imag2 * imag2;
|
||||
|
||||
/* read imaginary input sample from source buffer */
|
||||
imag3 = pSrc[5];
|
||||
|
||||
/* calculate power of real value */
|
||||
mul5 = real3 * real3;
|
||||
/* calculate power of imaginary value */
|
||||
mul6 = imag3 * imag3;
|
||||
|
||||
/* read real input sample from source buffer */
|
||||
real4 = pSrc[6];
|
||||
|
||||
/* accumulate real and imaginary powers */
|
||||
out1 = mul1 + mul2;
|
||||
|
||||
/* read imaginary input sample from source buffer */
|
||||
imag4 = pSrc[7];
|
||||
|
||||
/* accumulate real and imaginary powers */
|
||||
out2 = mul3 + mul4;
|
||||
|
||||
/* calculate power of real value */
|
||||
mul7 = real4 * real4;
|
||||
/* calculate power of imaginary value */
|
||||
mul8 = imag4 * imag4;
|
||||
|
||||
/* store output to destination */
|
||||
pDst[0] = out1;
|
||||
|
||||
/* accumulate real and imaginary powers */
|
||||
out3 = mul5 + mul6;
|
||||
|
||||
/* store output to destination */
|
||||
pDst[1] = out2;
|
||||
|
||||
/* accumulate real and imaginary powers */
|
||||
out4 = mul7 + mul8;
|
||||
|
||||
/* store output to destination */
|
||||
pDst[2] = out3;
|
||||
|
||||
/* increment destination pointer by 8 to process next samples */
|
||||
pSrc += 8u;
|
||||
|
||||
/* store output to destination */
|
||||
pDst[3] = out4;
|
||||
|
||||
/* increment destination pointer by 4 to process next samples */
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
blkCnt = numSamples;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[0] = (A[0] * A[0] + A[1] * A[1]) */
|
||||
real = *pSrc++;
|
||||
imag = *pSrc++;
|
||||
|
||||
/* out = (real * real) + (imag * imag) */
|
||||
/* store the result in the destination buffer. */
|
||||
*pDst++ = (real * real) + (imag * imag);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of cmplx_mag_squared group
|
||||
*/
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_mag_squared_q15.c
|
||||
*
|
||||
* Description: Q15 complex magnitude squared.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup cmplx_mag_squared
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q15 complex magnitude squared
|
||||
* @param *pSrc points to the complex input vector
|
||||
* @param *pDst points to the real output vector
|
||||
* @param numSamples number of complex samples in the input vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function implements 1.15 by 1.15 multiplications and finally output is converted into 3.13 format.
|
||||
*/
|
||||
|
||||
void arm_cmplx_mag_squared_q15(
|
||||
q15_t * pSrc,
|
||||
q15_t * pDst,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
q31_t acc0, acc1; /* Accumulators */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
q31_t in1, in2, in3, in4;
|
||||
q31_t acc2, acc3;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[0] = (A[0] * A[0] + A[1] * A[1]) */
|
||||
in1 = *__SIMD32(pSrc)++;
|
||||
in2 = *__SIMD32(pSrc)++;
|
||||
in3 = *__SIMD32(pSrc)++;
|
||||
in4 = *__SIMD32(pSrc)++;
|
||||
|
||||
acc0 = __SMUAD(in1, in1);
|
||||
acc1 = __SMUAD(in2, in2);
|
||||
acc2 = __SMUAD(in3, in3);
|
||||
acc3 = __SMUAD(in4, in4);
|
||||
|
||||
/* store the result in 3.13 format in the destination buffer. */
|
||||
*pDst++ = (q15_t) (acc0 >> 17);
|
||||
*pDst++ = (q15_t) (acc1 >> 17);
|
||||
*pDst++ = (q15_t) (acc2 >> 17);
|
||||
*pDst++ = (q15_t) (acc3 >> 17);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[0] = (A[0] * A[0] + A[1] * A[1]) */
|
||||
in1 = *__SIMD32(pSrc)++;
|
||||
acc0 = __SMUAD(in1, in1);
|
||||
|
||||
/* store the result in 3.13 format in the destination buffer. */
|
||||
*pDst++ = (q15_t) (acc0 >> 17);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
q15_t real, imag; /* Temporary variables to store real and imaginary values */
|
||||
|
||||
while(numSamples > 0u)
|
||||
{
|
||||
/* out = ((real * real) + (imag * imag)) */
|
||||
real = *pSrc++;
|
||||
imag = *pSrc++;
|
||||
acc0 = (real * real);
|
||||
acc1 = (imag * imag);
|
||||
/* store the result in 3.13 format in the destination buffer. */
|
||||
*pDst++ = (q15_t) (((q63_t) acc0 + acc1) >> 17);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
numSamples--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of cmplx_mag_squared group
|
||||
*/
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_mag_squared_q31.c
|
||||
*
|
||||
* Description: Q31 complex magnitude squared.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup cmplx_mag_squared
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Q31 complex magnitude squared
|
||||
* @param *pSrc points to the complex input vector
|
||||
* @param *pDst points to the real output vector
|
||||
* @param numSamples number of complex samples in the input vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function implements 1.31 by 1.31 multiplications and finally output is converted into 3.29 format.
|
||||
* Input down scaling is not required.
|
||||
*/
|
||||
|
||||
void arm_cmplx_mag_squared_q31(
|
||||
q31_t * pSrc,
|
||||
q31_t * pDst,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
q31_t real, imag; /* Temporary variables to store real and imaginary values */
|
||||
q31_t acc0, acc1; /* Accumulators */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
/* loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[0] = (A[0] * A[0] + A[1] * A[1]) */
|
||||
real = *pSrc++;
|
||||
imag = *pSrc++;
|
||||
acc0 = (q31_t) (((q63_t) real * real) >> 33);
|
||||
acc1 = (q31_t) (((q63_t) imag * imag) >> 33);
|
||||
/* store the result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = acc0 + acc1;
|
||||
|
||||
real = *pSrc++;
|
||||
imag = *pSrc++;
|
||||
acc0 = (q31_t) (((q63_t) real * real) >> 33);
|
||||
acc1 = (q31_t) (((q63_t) imag * imag) >> 33);
|
||||
/* store the result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = acc0 + acc1;
|
||||
|
||||
real = *pSrc++;
|
||||
imag = *pSrc++;
|
||||
acc0 = (q31_t) (((q63_t) real * real) >> 33);
|
||||
acc1 = (q31_t) (((q63_t) imag * imag) >> 33);
|
||||
/* store the result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = acc0 + acc1;
|
||||
|
||||
real = *pSrc++;
|
||||
imag = *pSrc++;
|
||||
acc0 = (q31_t) (((q63_t) real * real) >> 33);
|
||||
acc1 = (q31_t) (((q63_t) imag * imag) >> 33);
|
||||
/* store the result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = acc0 + acc1;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[0] = (A[0] * A[0] + A[1] * A[1]) */
|
||||
real = *pSrc++;
|
||||
imag = *pSrc++;
|
||||
acc0 = (q31_t) (((q63_t) real * real) >> 33);
|
||||
acc1 = (q31_t) (((q63_t) imag * imag) >> 33);
|
||||
/* store the result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = acc0 + acc1;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
while(numSamples > 0u)
|
||||
{
|
||||
/* out = ((real * real) + (imag * imag)) */
|
||||
real = *pSrc++;
|
||||
imag = *pSrc++;
|
||||
acc0 = (q31_t) (((q63_t) real * real) >> 33);
|
||||
acc1 = (q31_t) (((q63_t) imag * imag) >> 33);
|
||||
/* store the result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = acc0 + acc1;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
numSamples--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of cmplx_mag_squared group
|
||||
*/
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_mult_cmplx_f32.c
|
||||
*
|
||||
* Description: Floating-point complex-by-complex multiplication
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup CmplxByCmplxMult Complex-by-Complex Multiplication
|
||||
*
|
||||
* Multiplies a complex vector by another complex vector and generates a complex result.
|
||||
* The data in the complex arrays is stored in an interleaved fashion
|
||||
* (real, imag, real, imag, ...).
|
||||
* The parameter <code>numSamples</code> represents the number of complex
|
||||
* samples processed. The complex arrays have a total of <code>2*numSamples</code>
|
||||
* real values.
|
||||
*
|
||||
* The underlying algorithm is used:
|
||||
*
|
||||
* <pre>
|
||||
* for(n=0; n<numSamples; n++) {
|
||||
* pDst[(2*n)+0] = pSrcA[(2*n)+0] * pSrcB[(2*n)+0] - pSrcA[(2*n)+1] * pSrcB[(2*n)+1];
|
||||
* pDst[(2*n)+1] = pSrcA[(2*n)+0] * pSrcB[(2*n)+1] + pSrcA[(2*n)+1] * pSrcB[(2*n)+0];
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* There are separate functions for floating-point, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup CmplxByCmplxMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Floating-point complex-by-complex multiplication
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] numSamples number of complex samples in each vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
void arm_cmplx_mult_cmplx_f32(
|
||||
float32_t * pSrcA,
|
||||
float32_t * pSrcB,
|
||||
float32_t * pDst,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
float32_t a1, b1, c1, d1; /* Temporary variables to store real and imaginary values */
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
float32_t a2, b2, c2, d2; /* Temporary variables to store real and imaginary values */
|
||||
float32_t acc1, acc2, acc3, acc4;
|
||||
|
||||
|
||||
/* loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1]. */
|
||||
/* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i]. */
|
||||
a1 = *pSrcA; /* A[2 * i] */
|
||||
c1 = *pSrcB; /* B[2 * i] */
|
||||
|
||||
b1 = *(pSrcA + 1); /* A[2 * i + 1] */
|
||||
acc1 = a1 * c1; /* acc1 = A[2 * i] * B[2 * i] */
|
||||
|
||||
a2 = *(pSrcA + 2); /* A[2 * i + 2] */
|
||||
acc2 = (b1 * c1); /* acc2 = A[2 * i + 1] * B[2 * i] */
|
||||
|
||||
d1 = *(pSrcB + 1); /* B[2 * i + 1] */
|
||||
c2 = *(pSrcB + 2); /* B[2 * i + 2] */
|
||||
acc1 -= b1 * d1; /* acc1 = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1] */
|
||||
|
||||
d2 = *(pSrcB + 3); /* B[2 * i + 3] */
|
||||
acc3 = a2 * c2; /* acc3 = A[2 * i + 2] * B[2 * i + 2] */
|
||||
|
||||
b2 = *(pSrcA + 3); /* A[2 * i + 3] */
|
||||
acc2 += (a1 * d1); /* acc2 = A[2 * i + 1] * B[2 * i] + A[2 * i] * B[2 * i + 1] */
|
||||
|
||||
a1 = *(pSrcA + 4); /* A[2 * i + 4] */
|
||||
acc4 = (a2 * d2); /* acc4 = A[2 * i + 2] * B[2 * i + 3] */
|
||||
|
||||
c1 = *(pSrcB + 4); /* B[2 * i + 4] */
|
||||
acc3 -= (b2 * d2); /* acc3 = A[2 * i + 2] * B[2 * i + 2] - A[2 * i + 3] * B[2 * i + 3] */
|
||||
*pDst = acc1; /* C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1] */
|
||||
|
||||
b1 = *(pSrcA + 5); /* A[2 * i + 5] */
|
||||
acc4 += b2 * c2; /* acc4 = A[2 * i + 2] * B[2 * i + 3] + A[2 * i + 3] * B[2 * i + 2] */
|
||||
|
||||
*(pDst + 1) = acc2; /* C[2 * i + 1] = A[2 * i + 1] * B[2 * i] + A[2 * i] * B[2 * i + 1] */
|
||||
acc1 = (a1 * c1);
|
||||
|
||||
d1 = *(pSrcB + 5);
|
||||
acc2 = (b1 * c1);
|
||||
|
||||
*(pDst + 2) = acc3;
|
||||
*(pDst + 3) = acc4;
|
||||
|
||||
a2 = *(pSrcA + 6);
|
||||
acc1 -= (b1 * d1);
|
||||
|
||||
c2 = *(pSrcB + 6);
|
||||
acc2 += (a1 * d1);
|
||||
|
||||
b2 = *(pSrcA + 7);
|
||||
acc3 = (a2 * c2);
|
||||
|
||||
d2 = *(pSrcB + 7);
|
||||
acc4 = (b2 * c2);
|
||||
|
||||
*(pDst + 4) = acc1;
|
||||
pSrcA += 8u;
|
||||
|
||||
acc3 -= (b2 * d2);
|
||||
acc4 += (a2 * d2);
|
||||
|
||||
*(pDst + 5) = acc2;
|
||||
pSrcB += 8u;
|
||||
|
||||
*(pDst + 6) = acc3;
|
||||
*(pDst + 7) = acc4;
|
||||
|
||||
pDst += 8u;
|
||||
|
||||
/* Decrement the numSamples loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
blkCnt = numSamples;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1]. */
|
||||
/* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i]. */
|
||||
a1 = *pSrcA++;
|
||||
b1 = *pSrcA++;
|
||||
c1 = *pSrcB++;
|
||||
d1 = *pSrcB++;
|
||||
|
||||
/* store the result in the destination buffer. */
|
||||
*pDst++ = (a1 * c1) - (b1 * d1);
|
||||
*pDst++ = (a1 * d1) + (b1 * c1);
|
||||
|
||||
/* Decrement the numSamples loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of CmplxByCmplxMult group
|
||||
*/
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_mult_cmplx_q15.c
|
||||
*
|
||||
* Description: Q15 complex-by-complex multiplication
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup CmplxByCmplxMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q15 complex-by-complex multiplication
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] numSamples number of complex samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function implements 1.15 by 1.15 multiplications and finally output is converted into 3.13 format.
|
||||
*/
|
||||
|
||||
void arm_cmplx_mult_cmplx_q15(
|
||||
q15_t * pSrcA,
|
||||
q15_t * pSrcB,
|
||||
q15_t * pDst,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
q15_t a, b, c, d; /* Temporary variables to store real and imaginary values */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
|
||||
/* loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1]. */
|
||||
/* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i]. */
|
||||
a = *pSrcA++;
|
||||
b = *pSrcA++;
|
||||
c = *pSrcB++;
|
||||
d = *pSrcB++;
|
||||
|
||||
/* store the result in 3.13 format in the destination buffer. */
|
||||
*pDst++ =
|
||||
(q15_t) (q31_t) (((q31_t) a * c) >> 17) - (((q31_t) b * d) >> 17);
|
||||
/* store the result in 3.13 format in the destination buffer. */
|
||||
*pDst++ =
|
||||
(q15_t) (q31_t) (((q31_t) a * d) >> 17) + (((q31_t) b * c) >> 17);
|
||||
|
||||
a = *pSrcA++;
|
||||
b = *pSrcA++;
|
||||
c = *pSrcB++;
|
||||
d = *pSrcB++;
|
||||
|
||||
/* store the result in 3.13 format in the destination buffer. */
|
||||
*pDst++ =
|
||||
(q15_t) (q31_t) (((q31_t) a * c) >> 17) - (((q31_t) b * d) >> 17);
|
||||
/* store the result in 3.13 format in the destination buffer. */
|
||||
*pDst++ =
|
||||
(q15_t) (q31_t) (((q31_t) a * d) >> 17) + (((q31_t) b * c) >> 17);
|
||||
|
||||
a = *pSrcA++;
|
||||
b = *pSrcA++;
|
||||
c = *pSrcB++;
|
||||
d = *pSrcB++;
|
||||
|
||||
/* store the result in 3.13 format in the destination buffer. */
|
||||
*pDst++ =
|
||||
(q15_t) (q31_t) (((q31_t) a * c) >> 17) - (((q31_t) b * d) >> 17);
|
||||
/* store the result in 3.13 format in the destination buffer. */
|
||||
*pDst++ =
|
||||
(q15_t) (q31_t) (((q31_t) a * d) >> 17) + (((q31_t) b * c) >> 17);
|
||||
|
||||
a = *pSrcA++;
|
||||
b = *pSrcA++;
|
||||
c = *pSrcB++;
|
||||
d = *pSrcB++;
|
||||
|
||||
/* store the result in 3.13 format in the destination buffer. */
|
||||
*pDst++ =
|
||||
(q15_t) (q31_t) (((q31_t) a * c) >> 17) - (((q31_t) b * d) >> 17);
|
||||
/* store the result in 3.13 format in the destination buffer. */
|
||||
*pDst++ =
|
||||
(q15_t) (q31_t) (((q31_t) a * d) >> 17) + (((q31_t) b * c) >> 17);
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1]. */
|
||||
/* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i]. */
|
||||
a = *pSrcA++;
|
||||
b = *pSrcA++;
|
||||
c = *pSrcB++;
|
||||
d = *pSrcB++;
|
||||
|
||||
/* store the result in 3.13 format in the destination buffer. */
|
||||
*pDst++ =
|
||||
(q15_t) (q31_t) (((q31_t) a * c) >> 17) - (((q31_t) b * d) >> 17);
|
||||
/* store the result in 3.13 format in the destination buffer. */
|
||||
*pDst++ =
|
||||
(q15_t) (q31_t) (((q31_t) a * d) >> 17) + (((q31_t) b * c) >> 17);
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
while(numSamples > 0u)
|
||||
{
|
||||
/* C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1]. */
|
||||
/* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i]. */
|
||||
a = *pSrcA++;
|
||||
b = *pSrcA++;
|
||||
c = *pSrcB++;
|
||||
d = *pSrcB++;
|
||||
|
||||
/* store the result in 3.13 format in the destination buffer. */
|
||||
*pDst++ =
|
||||
(q15_t) (q31_t) (((q31_t) a * c) >> 17) - (((q31_t) b * d) >> 17);
|
||||
/* store the result in 3.13 format in the destination buffer. */
|
||||
*pDst++ =
|
||||
(q15_t) (q31_t) (((q31_t) a * d) >> 17) + (((q31_t) b * c) >> 17);
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
numSamples--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of CmplxByCmplxMult group
|
||||
*/
|
||||
+326
@@ -0,0 +1,326 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_mult_cmplx_q31.c
|
||||
*
|
||||
* Description: Q31 complex-by-complex multiplication
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup CmplxByCmplxMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Q31 complex-by-complex multiplication
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] numSamples number of complex samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function implements 1.31 by 1.31 multiplications and finally output is converted into 3.29 format.
|
||||
* Input down scaling is not required.
|
||||
*/
|
||||
|
||||
void arm_cmplx_mult_cmplx_q31(
|
||||
q31_t * pSrcA,
|
||||
q31_t * pSrcB,
|
||||
q31_t * pDst,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
q31_t a, b, c, d; /* Temporary variables to store real and imaginary values */
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
q31_t mul1, mul2, mul3, mul4;
|
||||
q31_t out1, out2;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
/* loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1]. */
|
||||
/* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i]. */
|
||||
a = *pSrcA++;
|
||||
b = *pSrcA++;
|
||||
c = *pSrcB++;
|
||||
d = *pSrcB++;
|
||||
|
||||
mul1 = (q31_t) (((q63_t) a * c) >> 32);
|
||||
mul2 = (q31_t) (((q63_t) b * d) >> 32);
|
||||
mul3 = (q31_t) (((q63_t) a * d) >> 32);
|
||||
mul4 = (q31_t) (((q63_t) b * c) >> 32);
|
||||
|
||||
mul1 = (mul1 >> 1);
|
||||
mul2 = (mul2 >> 1);
|
||||
mul3 = (mul3 >> 1);
|
||||
mul4 = (mul4 >> 1);
|
||||
|
||||
out1 = mul1 - mul2;
|
||||
out2 = mul3 + mul4;
|
||||
|
||||
/* store the real result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = out1;
|
||||
/* store the imag result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = out2;
|
||||
|
||||
a = *pSrcA++;
|
||||
b = *pSrcA++;
|
||||
c = *pSrcB++;
|
||||
d = *pSrcB++;
|
||||
|
||||
mul1 = (q31_t) (((q63_t) a * c) >> 32);
|
||||
mul2 = (q31_t) (((q63_t) b * d) >> 32);
|
||||
mul3 = (q31_t) (((q63_t) a * d) >> 32);
|
||||
mul4 = (q31_t) (((q63_t) b * c) >> 32);
|
||||
|
||||
mul1 = (mul1 >> 1);
|
||||
mul2 = (mul2 >> 1);
|
||||
mul3 = (mul3 >> 1);
|
||||
mul4 = (mul4 >> 1);
|
||||
|
||||
out1 = mul1 - mul2;
|
||||
out2 = mul3 + mul4;
|
||||
|
||||
/* store the real result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = out1;
|
||||
/* store the imag result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = out2;
|
||||
|
||||
a = *pSrcA++;
|
||||
b = *pSrcA++;
|
||||
c = *pSrcB++;
|
||||
d = *pSrcB++;
|
||||
|
||||
mul1 = (q31_t) (((q63_t) a * c) >> 32);
|
||||
mul2 = (q31_t) (((q63_t) b * d) >> 32);
|
||||
mul3 = (q31_t) (((q63_t) a * d) >> 32);
|
||||
mul4 = (q31_t) (((q63_t) b * c) >> 32);
|
||||
|
||||
mul1 = (mul1 >> 1);
|
||||
mul2 = (mul2 >> 1);
|
||||
mul3 = (mul3 >> 1);
|
||||
mul4 = (mul4 >> 1);
|
||||
|
||||
out1 = mul1 - mul2;
|
||||
out2 = mul3 + mul4;
|
||||
|
||||
/* store the real result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = out1;
|
||||
/* store the imag result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = out2;
|
||||
|
||||
a = *pSrcA++;
|
||||
b = *pSrcA++;
|
||||
c = *pSrcB++;
|
||||
d = *pSrcB++;
|
||||
|
||||
mul1 = (q31_t) (((q63_t) a * c) >> 32);
|
||||
mul2 = (q31_t) (((q63_t) b * d) >> 32);
|
||||
mul3 = (q31_t) (((q63_t) a * d) >> 32);
|
||||
mul4 = (q31_t) (((q63_t) b * c) >> 32);
|
||||
|
||||
mul1 = (mul1 >> 1);
|
||||
mul2 = (mul2 >> 1);
|
||||
mul3 = (mul3 >> 1);
|
||||
mul4 = (mul4 >> 1);
|
||||
|
||||
out1 = mul1 - mul2;
|
||||
out2 = mul3 + mul4;
|
||||
|
||||
/* store the real result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = out1;
|
||||
/* store the imag result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = out2;
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1]. */
|
||||
/* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i]. */
|
||||
a = *pSrcA++;
|
||||
b = *pSrcA++;
|
||||
c = *pSrcB++;
|
||||
d = *pSrcB++;
|
||||
|
||||
mul1 = (q31_t) (((q63_t) a * c) >> 32);
|
||||
mul2 = (q31_t) (((q63_t) b * d) >> 32);
|
||||
mul3 = (q31_t) (((q63_t) a * d) >> 32);
|
||||
mul4 = (q31_t) (((q63_t) b * c) >> 32);
|
||||
|
||||
mul1 = (mul1 >> 1);
|
||||
mul2 = (mul2 >> 1);
|
||||
mul3 = (mul3 >> 1);
|
||||
mul4 = (mul4 >> 1);
|
||||
|
||||
out1 = mul1 - mul2;
|
||||
out2 = mul3 + mul4;
|
||||
|
||||
/* store the real result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = out1;
|
||||
/* store the imag result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = out2;
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* loop Unrolling */
|
||||
blkCnt = numSamples >> 1u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 2 outputs at a time.
|
||||
** a second loop below computes the remaining 1 sample. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1]. */
|
||||
/* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i]. */
|
||||
a = *pSrcA++;
|
||||
b = *pSrcA++;
|
||||
c = *pSrcB++;
|
||||
d = *pSrcB++;
|
||||
|
||||
mul1 = (q31_t) (((q63_t) a * c) >> 32);
|
||||
mul2 = (q31_t) (((q63_t) b * d) >> 32);
|
||||
mul3 = (q31_t) (((q63_t) a * d) >> 32);
|
||||
mul4 = (q31_t) (((q63_t) b * c) >> 32);
|
||||
|
||||
mul1 = (mul1 >> 1);
|
||||
mul2 = (mul2 >> 1);
|
||||
mul3 = (mul3 >> 1);
|
||||
mul4 = (mul4 >> 1);
|
||||
|
||||
out1 = mul1 - mul2;
|
||||
out2 = mul3 + mul4;
|
||||
|
||||
/* store the real result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = out1;
|
||||
/* store the imag result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = out2;
|
||||
|
||||
a = *pSrcA++;
|
||||
b = *pSrcA++;
|
||||
c = *pSrcB++;
|
||||
d = *pSrcB++;
|
||||
|
||||
mul1 = (q31_t) (((q63_t) a * c) >> 32);
|
||||
mul2 = (q31_t) (((q63_t) b * d) >> 32);
|
||||
mul3 = (q31_t) (((q63_t) a * d) >> 32);
|
||||
mul4 = (q31_t) (((q63_t) b * c) >> 32);
|
||||
|
||||
mul1 = (mul1 >> 1);
|
||||
mul2 = (mul2 >> 1);
|
||||
mul3 = (mul3 >> 1);
|
||||
mul4 = (mul4 >> 1);
|
||||
|
||||
out1 = mul1 - mul2;
|
||||
out2 = mul3 + mul4;
|
||||
|
||||
/* store the real result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = out1;
|
||||
/* store the imag result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = out2;
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 2, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x2u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1]. */
|
||||
/* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i]. */
|
||||
a = *pSrcA++;
|
||||
b = *pSrcA++;
|
||||
c = *pSrcB++;
|
||||
d = *pSrcB++;
|
||||
|
||||
mul1 = (q31_t) (((q63_t) a * c) >> 32);
|
||||
mul2 = (q31_t) (((q63_t) b * d) >> 32);
|
||||
mul3 = (q31_t) (((q63_t) a * d) >> 32);
|
||||
mul4 = (q31_t) (((q63_t) b * c) >> 32);
|
||||
|
||||
mul1 = (mul1 >> 1);
|
||||
mul2 = (mul2 >> 1);
|
||||
mul3 = (mul3 >> 1);
|
||||
mul4 = (mul4 >> 1);
|
||||
|
||||
out1 = mul1 - mul2;
|
||||
out2 = mul3 + mul4;
|
||||
|
||||
/* store the real result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = out1;
|
||||
/* store the imag result in 3.29 format in the destination buffer. */
|
||||
*pDst++ = out2;
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of CmplxByCmplxMult group
|
||||
*/
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_mult_real_f32.c
|
||||
*
|
||||
* Description: Floating-point complex by real multiplication
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup CmplxByRealMult Complex-by-Real Multiplication
|
||||
*
|
||||
* Multiplies a complex vector by a real vector and generates a complex result.
|
||||
* The data in the complex arrays is stored in an interleaved fashion
|
||||
* (real, imag, real, imag, ...).
|
||||
* The parameter <code>numSamples</code> represents the number of complex
|
||||
* samples processed. The complex arrays have a total of <code>2*numSamples</code>
|
||||
* real values while the real array has a total of <code>numSamples</code>
|
||||
* real values.
|
||||
*
|
||||
* The underlying algorithm is used:
|
||||
*
|
||||
* <pre>
|
||||
* for(n=0; n<numSamples; n++) {
|
||||
* pCmplxDst[(2*n)+0] = pSrcCmplx[(2*n)+0] * pSrcReal[n];
|
||||
* pCmplxDst[(2*n)+1] = pSrcCmplx[(2*n)+1] * pSrcReal[n];
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* There are separate functions for floating-point, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup CmplxByRealMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Floating-point complex-by-real multiplication
|
||||
* @param[in] *pSrcCmplx points to the complex input vector
|
||||
* @param[in] *pSrcReal points to the real input vector
|
||||
* @param[out] *pCmplxDst points to the complex output vector
|
||||
* @param[in] numSamples number of samples in each vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
void arm_cmplx_mult_real_f32(
|
||||
float32_t * pSrcCmplx,
|
||||
float32_t * pSrcReal,
|
||||
float32_t * pCmplxDst,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
float32_t in; /* Temporary variable to store input value */
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
float32_t inA1, inA2, inA3, inA4; /* Temporary variables to hold input data */
|
||||
float32_t inA5, inA6, inA7, inA8; /* Temporary variables to hold input data */
|
||||
float32_t inB1, inB2, inB3, inB4; /* Temporary variables to hold input data */
|
||||
float32_t out1, out2, out3, out4; /* Temporary variables to hold output data */
|
||||
float32_t out5, out6, out7, out8; /* Temporary variables to hold output data */
|
||||
|
||||
/* loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[2 * i] = A[2 * i] * B[i]. */
|
||||
/* C[2 * i + 1] = A[2 * i + 1] * B[i]. */
|
||||
/* read input from complex input buffer */
|
||||
inA1 = pSrcCmplx[0];
|
||||
inA2 = pSrcCmplx[1];
|
||||
/* read input from real input buffer */
|
||||
inB1 = pSrcReal[0];
|
||||
|
||||
/* read input from complex input buffer */
|
||||
inA3 = pSrcCmplx[2];
|
||||
|
||||
/* multiply complex buffer real input with real buffer input */
|
||||
out1 = inA1 * inB1;
|
||||
|
||||
/* read input from complex input buffer */
|
||||
inA4 = pSrcCmplx[3];
|
||||
|
||||
/* multiply complex buffer imaginary input with real buffer input */
|
||||
out2 = inA2 * inB1;
|
||||
|
||||
/* read input from real input buffer */
|
||||
inB2 = pSrcReal[1];
|
||||
/* read input from complex input buffer */
|
||||
inA5 = pSrcCmplx[4];
|
||||
|
||||
/* multiply complex buffer real input with real buffer input */
|
||||
out3 = inA3 * inB2;
|
||||
|
||||
/* read input from complex input buffer */
|
||||
inA6 = pSrcCmplx[5];
|
||||
/* read input from real input buffer */
|
||||
inB3 = pSrcReal[2];
|
||||
|
||||
/* multiply complex buffer imaginary input with real buffer input */
|
||||
out4 = inA4 * inB2;
|
||||
|
||||
/* read input from complex input buffer */
|
||||
inA7 = pSrcCmplx[6];
|
||||
|
||||
/* multiply complex buffer real input with real buffer input */
|
||||
out5 = inA5 * inB3;
|
||||
|
||||
/* read input from complex input buffer */
|
||||
inA8 = pSrcCmplx[7];
|
||||
|
||||
/* multiply complex buffer imaginary input with real buffer input */
|
||||
out6 = inA6 * inB3;
|
||||
|
||||
/* read input from real input buffer */
|
||||
inB4 = pSrcReal[3];
|
||||
|
||||
/* store result to destination bufer */
|
||||
pCmplxDst[0] = out1;
|
||||
|
||||
/* multiply complex buffer real input with real buffer input */
|
||||
out7 = inA7 * inB4;
|
||||
|
||||
/* store result to destination bufer */
|
||||
pCmplxDst[1] = out2;
|
||||
|
||||
/* multiply complex buffer imaginary input with real buffer input */
|
||||
out8 = inA8 * inB4;
|
||||
|
||||
/* store result to destination bufer */
|
||||
pCmplxDst[2] = out3;
|
||||
pCmplxDst[3] = out4;
|
||||
pCmplxDst[4] = out5;
|
||||
|
||||
/* incremnet complex input buffer by 8 to process next samples */
|
||||
pSrcCmplx += 8u;
|
||||
|
||||
/* store result to destination bufer */
|
||||
pCmplxDst[5] = out6;
|
||||
|
||||
/* increment real input buffer by 4 to process next samples */
|
||||
pSrcReal += 4u;
|
||||
|
||||
/* store result to destination bufer */
|
||||
pCmplxDst[6] = out7;
|
||||
pCmplxDst[7] = out8;
|
||||
|
||||
/* increment destination buffer by 8 to process next sampels */
|
||||
pCmplxDst += 8u;
|
||||
|
||||
/* Decrement the numSamples loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
blkCnt = numSamples;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[2 * i] = A[2 * i] * B[i]. */
|
||||
/* C[2 * i + 1] = A[2 * i + 1] * B[i]. */
|
||||
in = *pSrcReal++;
|
||||
/* store the result in the destination buffer. */
|
||||
*pCmplxDst++ = (*pSrcCmplx++) * (in);
|
||||
*pCmplxDst++ = (*pSrcCmplx++) * (in);
|
||||
|
||||
/* Decrement the numSamples loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of CmplxByRealMult group
|
||||
*/
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. October 2015
|
||||
* $Revision: V.1.4.5 a
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_mult_real_q15.c
|
||||
*
|
||||
* Description: Q15 complex by real multiplication
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup CmplxByRealMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Q15 complex-by-real multiplication
|
||||
* @param[in] *pSrcCmplx points to the complex input vector
|
||||
* @param[in] *pSrcReal points to the real input vector
|
||||
* @param[out] *pCmplxDst points to the complex output vector
|
||||
* @param[in] numSamples number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_cmplx_mult_real_q15(
|
||||
q15_t * pSrcCmplx,
|
||||
q15_t * pSrcReal,
|
||||
q15_t * pCmplxDst,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
q15_t in; /* Temporary variable to store input value */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
q31_t inA1, inA2; /* Temporary variables to hold input data */
|
||||
q31_t inB1; /* Temporary variables to hold input data */
|
||||
q15_t out1, out2, out3, out4; /* Temporary variables to hold output data */
|
||||
q31_t mul1, mul2, mul3, mul4; /* Temporary variables to hold intermediate data */
|
||||
|
||||
/* loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[2 * i] = A[2 * i] * B[i]. */
|
||||
/* C[2 * i + 1] = A[2 * i + 1] * B[i]. */
|
||||
/* read complex number both real and imaginary from complex input buffer */
|
||||
inA1 = *__SIMD32(pSrcCmplx)++;
|
||||
/* read two real values at a time from real input buffer */
|
||||
inB1 = *__SIMD32(pSrcReal)++;
|
||||
/* read complex number both real and imaginary from complex input buffer */
|
||||
inA2 = *__SIMD32(pSrcCmplx)++;
|
||||
|
||||
/* multiply complex number with real numbers */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
mul1 = (q31_t) ((q15_t) (inA1) * (q15_t) (inB1));
|
||||
mul2 = (q31_t) ((q15_t) (inA1 >> 16) * (q15_t) (inB1));
|
||||
mul3 = (q31_t) ((q15_t) (inA2) * (q15_t) (inB1 >> 16));
|
||||
mul4 = (q31_t) ((q15_t) (inA2 >> 16) * (q15_t) (inB1 >> 16));
|
||||
|
||||
#else
|
||||
|
||||
mul2 = (q31_t) ((q15_t) (inA1 >> 16) * (q15_t) (inB1 >> 16));
|
||||
mul1 = (q31_t) ((q15_t) inA1 * (q15_t) (inB1 >> 16));
|
||||
mul4 = (q31_t) ((q15_t) (inA2 >> 16) * (q15_t) inB1);
|
||||
mul3 = (q31_t) ((q15_t) inA2 * (q15_t) inB1);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* saturate the result */
|
||||
out1 = (q15_t) __SSAT(mul1 >> 15u, 16);
|
||||
out2 = (q15_t) __SSAT(mul2 >> 15u, 16);
|
||||
out3 = (q15_t) __SSAT(mul3 >> 15u, 16);
|
||||
out4 = (q15_t) __SSAT(mul4 >> 15u, 16);
|
||||
|
||||
/* pack real and imaginary outputs and store them to destination */
|
||||
*__SIMD32(pCmplxDst)++ = __PKHBT(out1, out2, 16);
|
||||
*__SIMD32(pCmplxDst)++ = __PKHBT(out3, out4, 16);
|
||||
|
||||
inA1 = *__SIMD32(pSrcCmplx)++;
|
||||
inB1 = *__SIMD32(pSrcReal)++;
|
||||
inA2 = *__SIMD32(pSrcCmplx)++;
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
mul1 = (q31_t) ((q15_t) (inA1) * (q15_t) (inB1));
|
||||
mul2 = (q31_t) ((q15_t) (inA1 >> 16) * (q15_t) (inB1));
|
||||
mul3 = (q31_t) ((q15_t) (inA2) * (q15_t) (inB1 >> 16));
|
||||
mul4 = (q31_t) ((q15_t) (inA2 >> 16) * (q15_t) (inB1 >> 16));
|
||||
|
||||
#else
|
||||
|
||||
mul2 = (q31_t) ((q15_t) (inA1 >> 16) * (q15_t) (inB1 >> 16));
|
||||
mul1 = (q31_t) ((q15_t) inA1 * (q15_t) (inB1 >> 16));
|
||||
mul4 = (q31_t) ((q15_t) (inA2 >> 16) * (q15_t) inB1);
|
||||
mul3 = (q31_t) ((q15_t) inA2 * (q15_t) inB1);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
out1 = (q15_t) __SSAT(mul1 >> 15u, 16);
|
||||
out2 = (q15_t) __SSAT(mul2 >> 15u, 16);
|
||||
out3 = (q15_t) __SSAT(mul3 >> 15u, 16);
|
||||
out4 = (q15_t) __SSAT(mul4 >> 15u, 16);
|
||||
|
||||
*__SIMD32(pCmplxDst)++ = __PKHBT(out1, out2, 16);
|
||||
*__SIMD32(pCmplxDst)++ = __PKHBT(out3, out4, 16);
|
||||
|
||||
/* Decrement the numSamples loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[2 * i] = A[2 * i] * B[i]. */
|
||||
/* C[2 * i + 1] = A[2 * i + 1] * B[i]. */
|
||||
in = *pSrcReal++;
|
||||
/* store the result in the destination buffer. */
|
||||
*pCmplxDst++ =
|
||||
(q15_t) __SSAT((((q31_t) (*pSrcCmplx++) * (in)) >> 15), 16);
|
||||
*pCmplxDst++ =
|
||||
(q15_t) __SSAT((((q31_t) (*pSrcCmplx++) * (in)) >> 15), 16);
|
||||
|
||||
/* Decrement the numSamples loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
while(numSamples > 0u)
|
||||
{
|
||||
/* realOut = realA * realB. */
|
||||
/* imagOut = imagA * realB. */
|
||||
in = *pSrcReal++;
|
||||
/* store the result in the destination buffer. */
|
||||
*pCmplxDst++ =
|
||||
(q15_t) __SSAT((((q31_t) (*pSrcCmplx++) * (in)) >> 15), 16);
|
||||
*pCmplxDst++ =
|
||||
(q15_t) __SSAT((((q31_t) (*pSrcCmplx++) * (in)) >> 15), 16);
|
||||
|
||||
/* Decrement the numSamples loop counter */
|
||||
numSamples--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of CmplxByRealMult group
|
||||
*/
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cmplx_mult_real_q31.c
|
||||
*
|
||||
* Description: Q31 complex by real multiplication
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupCmplxMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup CmplxByRealMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Q31 complex-by-real multiplication
|
||||
* @param[in] *pSrcCmplx points to the complex input vector
|
||||
* @param[in] *pSrcReal points to the real input vector
|
||||
* @param[out] *pCmplxDst points to the complex output vector
|
||||
* @param[in] numSamples number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q31 range[0x80000000 0x7FFFFFFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_cmplx_mult_real_q31(
|
||||
q31_t * pSrcCmplx,
|
||||
q31_t * pSrcReal,
|
||||
q31_t * pCmplxDst,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
q31_t inA1; /* Temporary variable to store input value */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
q31_t inA2, inA3, inA4; /* Temporary variables to hold input data */
|
||||
q31_t inB1, inB2; /* Temporary variabels to hold input data */
|
||||
q31_t out1, out2, out3, out4; /* Temporary variables to hold output data */
|
||||
|
||||
/* loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[2 * i] = A[2 * i] * B[i]. */
|
||||
/* C[2 * i + 1] = A[2 * i + 1] * B[i]. */
|
||||
/* read real input from complex input buffer */
|
||||
inA1 = *pSrcCmplx++;
|
||||
inA2 = *pSrcCmplx++;
|
||||
/* read input from real input bufer */
|
||||
inB1 = *pSrcReal++;
|
||||
inB2 = *pSrcReal++;
|
||||
/* read imaginary input from complex input buffer */
|
||||
inA3 = *pSrcCmplx++;
|
||||
inA4 = *pSrcCmplx++;
|
||||
|
||||
/* multiply complex input with real input */
|
||||
out1 = ((q63_t) inA1 * inB1) >> 32;
|
||||
out2 = ((q63_t) inA2 * inB1) >> 32;
|
||||
out3 = ((q63_t) inA3 * inB2) >> 32;
|
||||
out4 = ((q63_t) inA4 * inB2) >> 32;
|
||||
|
||||
/* sature the result */
|
||||
out1 = __SSAT(out1, 31);
|
||||
out2 = __SSAT(out2, 31);
|
||||
out3 = __SSAT(out3, 31);
|
||||
out4 = __SSAT(out4, 31);
|
||||
|
||||
/* get result in 1.31 format */
|
||||
out1 = out1 << 1;
|
||||
out2 = out2 << 1;
|
||||
out3 = out3 << 1;
|
||||
out4 = out4 << 1;
|
||||
|
||||
/* store the result to destination buffer */
|
||||
*pCmplxDst++ = out1;
|
||||
*pCmplxDst++ = out2;
|
||||
*pCmplxDst++ = out3;
|
||||
*pCmplxDst++ = out4;
|
||||
|
||||
/* read real input from complex input buffer */
|
||||
inA1 = *pSrcCmplx++;
|
||||
inA2 = *pSrcCmplx++;
|
||||
/* read input from real input bufer */
|
||||
inB1 = *pSrcReal++;
|
||||
inB2 = *pSrcReal++;
|
||||
/* read imaginary input from complex input buffer */
|
||||
inA3 = *pSrcCmplx++;
|
||||
inA4 = *pSrcCmplx++;
|
||||
|
||||
/* multiply complex input with real input */
|
||||
out1 = ((q63_t) inA1 * inB1) >> 32;
|
||||
out2 = ((q63_t) inA2 * inB1) >> 32;
|
||||
out3 = ((q63_t) inA3 * inB2) >> 32;
|
||||
out4 = ((q63_t) inA4 * inB2) >> 32;
|
||||
|
||||
/* sature the result */
|
||||
out1 = __SSAT(out1, 31);
|
||||
out2 = __SSAT(out2, 31);
|
||||
out3 = __SSAT(out3, 31);
|
||||
out4 = __SSAT(out4, 31);
|
||||
|
||||
/* get result in 1.31 format */
|
||||
out1 = out1 << 1;
|
||||
out2 = out2 << 1;
|
||||
out3 = out3 << 1;
|
||||
out4 = out4 << 1;
|
||||
|
||||
/* store the result to destination buffer */
|
||||
*pCmplxDst++ = out1;
|
||||
*pCmplxDst++ = out2;
|
||||
*pCmplxDst++ = out3;
|
||||
*pCmplxDst++ = out4;
|
||||
|
||||
/* Decrement the numSamples loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C[2 * i] = A[2 * i] * B[i]. */
|
||||
/* C[2 * i + 1] = A[2 * i + 1] * B[i]. */
|
||||
/* read real input from complex input buffer */
|
||||
inA1 = *pSrcCmplx++;
|
||||
inA2 = *pSrcCmplx++;
|
||||
/* read input from real input bufer */
|
||||
inB1 = *pSrcReal++;
|
||||
|
||||
/* multiply complex input with real input */
|
||||
out1 = ((q63_t) inA1 * inB1) >> 32;
|
||||
out2 = ((q63_t) inA2 * inB1) >> 32;
|
||||
|
||||
/* sature the result */
|
||||
out1 = __SSAT(out1, 31);
|
||||
out2 = __SSAT(out2, 31);
|
||||
|
||||
/* get result in 1.31 format */
|
||||
out1 = out1 << 1;
|
||||
out2 = out2 << 1;
|
||||
|
||||
/* store the result to destination buffer */
|
||||
*pCmplxDst++ = out1;
|
||||
*pCmplxDst++ = out2;
|
||||
|
||||
/* Decrement the numSamples loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
while(numSamples > 0u)
|
||||
{
|
||||
/* realOut = realA * realB. */
|
||||
/* imagReal = imagA * realB. */
|
||||
inA1 = *pSrcReal++;
|
||||
/* store the result in the destination buffer. */
|
||||
*pCmplxDst++ =
|
||||
(q31_t) clip_q63_to_q31(((q63_t) * pSrcCmplx++ * inA1) >> 31);
|
||||
*pCmplxDst++ =
|
||||
(q31_t) clip_q63_to_q31(((q63_t) * pSrcCmplx++ * inA1) >> 31);
|
||||
|
||||
/* Decrement the numSamples loop counter */
|
||||
numSamples--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of CmplxByRealMult group
|
||||
*/
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_pid_init_f32.c
|
||||
*
|
||||
* Description: Floating-point PID Control initialization function
|
||||
*
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @addtogroup PID
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialization function for the floating-point PID Control.
|
||||
* @param[in,out] *S points to an instance of the PID structure.
|
||||
* @param[in] resetStateFlag flag to reset the state. 0 = no change in state & 1 = reset the state.
|
||||
* @return none.
|
||||
* \par Description:
|
||||
* \par
|
||||
* The <code>resetStateFlag</code> specifies whether to set state to zero or not. \n
|
||||
* The function computes the structure fields: <code>A0</code>, <code>A1</code> <code>A2</code>
|
||||
* using the proportional gain( \c Kp), integral gain( \c Ki) and derivative gain( \c Kd)
|
||||
* also sets the state variables to all zeros.
|
||||
*/
|
||||
|
||||
void arm_pid_init_f32(
|
||||
arm_pid_instance_f32 * S,
|
||||
int32_t resetStateFlag)
|
||||
{
|
||||
|
||||
/* Derived coefficient A0 */
|
||||
S->A0 = S->Kp + S->Ki + S->Kd;
|
||||
|
||||
/* Derived coefficient A1 */
|
||||
S->A1 = (-S->Kp) - ((float32_t) 2.0 * S->Kd);
|
||||
|
||||
/* Derived coefficient A2 */
|
||||
S->A2 = S->Kd;
|
||||
|
||||
/* Check whether state needs reset or not */
|
||||
if(resetStateFlag)
|
||||
{
|
||||
/* Clear the state buffer. The size will be always 3 samples */
|
||||
memset(S->state, 0, 3u * sizeof(float32_t));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of PID group
|
||||
*/
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_pid_init_q15.c
|
||||
*
|
||||
* Description: Q15 PID Control initialization function
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @addtogroup PID
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @details
|
||||
* @param[in,out] *S points to an instance of the Q15 PID structure.
|
||||
* @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state.
|
||||
* @return none.
|
||||
* \par Description:
|
||||
* \par
|
||||
* The <code>resetStateFlag</code> specifies whether to set state to zero or not. \n
|
||||
* The function computes the structure fields: <code>A0</code>, <code>A1</code> <code>A2</code>
|
||||
* using the proportional gain( \c Kp), integral gain( \c Ki) and derivative gain( \c Kd)
|
||||
* also sets the state variables to all zeros.
|
||||
*/
|
||||
|
||||
void arm_pid_init_q15(
|
||||
arm_pid_instance_q15 * S,
|
||||
int32_t resetStateFlag)
|
||||
{
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
/* Derived coefficient A0 */
|
||||
S->A0 = __QADD16(__QADD16(S->Kp, S->Ki), S->Kd);
|
||||
|
||||
/* Derived coefficients and pack into A1 */
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
S->A1 = __PKHBT(-__QADD16(__QADD16(S->Kd, S->Kd), S->Kp), S->Kd, 16);
|
||||
|
||||
#else
|
||||
|
||||
S->A1 = __PKHBT(S->Kd, -__QADD16(__QADD16(S->Kd, S->Kd), S->Kp), 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Check whether state needs reset or not */
|
||||
if(resetStateFlag)
|
||||
{
|
||||
/* Clear the state buffer. The size will be always 3 samples */
|
||||
memset(S->state, 0, 3u * sizeof(q15_t));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
q31_t temp; /*to store the sum */
|
||||
|
||||
/* Derived coefficient A0 */
|
||||
temp = S->Kp + S->Ki + S->Kd;
|
||||
S->A0 = (q15_t) __SSAT(temp, 16);
|
||||
|
||||
/* Derived coefficients and pack into A1 */
|
||||
temp = -(S->Kd + S->Kd + S->Kp);
|
||||
S->A1 = (q15_t) __SSAT(temp, 16);
|
||||
S->A2 = S->Kd;
|
||||
|
||||
|
||||
|
||||
/* Check whether state needs reset or not */
|
||||
if(resetStateFlag)
|
||||
{
|
||||
/* Clear the state buffer. The size will be always 3 samples */
|
||||
memset(S->state, 0, 3u * sizeof(q15_t));
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of PID group
|
||||
*/
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_pid_init_q31.c
|
||||
*
|
||||
* Description: Q31 PID Control initialization function
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @addtogroup PID
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialization function for the Q31 PID Control.
|
||||
* @param[in,out] *S points to an instance of the Q31 PID structure.
|
||||
* @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state.
|
||||
* @return none.
|
||||
* \par Description:
|
||||
* \par
|
||||
* The <code>resetStateFlag</code> specifies whether to set state to zero or not. \n
|
||||
* The function computes the structure fields: <code>A0</code>, <code>A1</code> <code>A2</code>
|
||||
* using the proportional gain( \c Kp), integral gain( \c Ki) and derivative gain( \c Kd)
|
||||
* also sets the state variables to all zeros.
|
||||
*/
|
||||
|
||||
void arm_pid_init_q31(
|
||||
arm_pid_instance_q31 * S,
|
||||
int32_t resetStateFlag)
|
||||
{
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
/* Derived coefficient A0 */
|
||||
S->A0 = __QADD(__QADD(S->Kp, S->Ki), S->Kd);
|
||||
|
||||
/* Derived coefficient A1 */
|
||||
S->A1 = -__QADD(__QADD(S->Kd, S->Kd), S->Kp);
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
q31_t temp;
|
||||
|
||||
/* Derived coefficient A0 */
|
||||
temp = clip_q63_to_q31((q63_t) S->Kp + S->Ki);
|
||||
S->A0 = clip_q63_to_q31((q63_t) temp + S->Kd);
|
||||
|
||||
/* Derived coefficient A1 */
|
||||
temp = clip_q63_to_q31((q63_t) S->Kd + S->Kd);
|
||||
S->A1 = -clip_q63_to_q31((q63_t) temp + S->Kp);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
/* Derived coefficient A2 */
|
||||
S->A2 = S->Kd;
|
||||
|
||||
/* Check whether state needs reset or not */
|
||||
if(resetStateFlag)
|
||||
{
|
||||
/* Clear the state buffer. The size will be always 3 samples */
|
||||
memset(S->state, 0, 3u * sizeof(q31_t));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of PID group
|
||||
*/
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_pid_reset_f32.c
|
||||
*
|
||||
* Description: Floating-point PID Control reset function
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @addtogroup PID
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Reset function for the floating-point PID Control.
|
||||
* @param[in] *S Instance pointer of PID control data structure.
|
||||
* @return none.
|
||||
* \par Description:
|
||||
* The function resets the state buffer to zeros.
|
||||
*/
|
||||
void arm_pid_reset_f32(
|
||||
arm_pid_instance_f32 * S)
|
||||
{
|
||||
|
||||
/* Clear the state buffer. The size will be always 3 samples */
|
||||
memset(S->state, 0, 3u * sizeof(float32_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of PID group
|
||||
*/
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_pid_reset_q15.c
|
||||
*
|
||||
* Description: Q15 PID Control reset function
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @addtogroup PID
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Reset function for the Q15 PID Control.
|
||||
* @param[in] *S Instance pointer of PID control data structure.
|
||||
* @return none.
|
||||
* \par Description:
|
||||
* The function resets the state buffer to zeros.
|
||||
*/
|
||||
void arm_pid_reset_q15(
|
||||
arm_pid_instance_q15 * S)
|
||||
{
|
||||
/* Reset state to zero, The size will be always 3 samples */
|
||||
memset(S->state, 0, 3u * sizeof(q15_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of PID group
|
||||
*/
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_pid_reset_q31.c
|
||||
*
|
||||
* Description: Q31 PID Control reset function
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @addtogroup PID
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Reset function for the Q31 PID Control.
|
||||
* @param[in] *S Instance pointer of PID control data structure.
|
||||
* @return none.
|
||||
* \par Description:
|
||||
* The function resets the state buffer to zeros.
|
||||
*/
|
||||
void arm_pid_reset_q31(
|
||||
arm_pid_instance_q31 * S)
|
||||
{
|
||||
|
||||
/* Clear the state buffer. The size will be always 3 samples */
|
||||
memset(S->state, 0, 3u * sizeof(q31_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of PID group
|
||||
*/
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_sin_cos_f32.c
|
||||
*
|
||||
* Description: Sine and Cosine calculation for floating-point values.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_common_tables.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupController
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup SinCos Sine Cosine
|
||||
*
|
||||
* Computes the trigonometric sine and cosine values using a combination of table lookup
|
||||
* and linear interpolation.
|
||||
* There are separate functions for Q31 and floating-point data types.
|
||||
* The input to the floating-point version is in degrees while the
|
||||
* fixed-point Q31 have a scaled input with the range
|
||||
* [-1 0.9999] mapping to [-180 +180] degrees.
|
||||
*
|
||||
* The floating point function also allows values that are out of the usual range. When this happens, the function will
|
||||
* take extra time to adjust the input value to the range of [-180 180].
|
||||
*
|
||||
* The implementation is based on table lookup using 360 values together with linear interpolation.
|
||||
* The steps used are:
|
||||
* -# Calculation of the nearest integer table index.
|
||||
* -# Compute the fractional portion (fract) of the input.
|
||||
* -# Fetch the value corresponding to \c index from sine table to \c y0 and also value from \c index+1 to \c y1.
|
||||
* -# Sine value is computed as <code> *psinVal = y0 + (fract * (y1 - y0))</code>.
|
||||
* -# Fetch the value corresponding to \c index from cosine table to \c y0 and also value from \c index+1 to \c y1.
|
||||
* -# Cosine value is computed as <code> *pcosVal = y0 + (fract * (y1 - y0))</code>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup SinCos
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Floating-point sin_cos function.
|
||||
* @param[in] theta input value in degrees
|
||||
* @param[out] *pSinVal points to the processed sine output.
|
||||
* @param[out] *pCosVal points to the processed cos output.
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
void arm_sin_cos_f32(
|
||||
float32_t theta,
|
||||
float32_t * pSinVal,
|
||||
float32_t * pCosVal)
|
||||
{
|
||||
float32_t fract, in; /* Temporary variables for input, output */
|
||||
uint16_t indexS, indexC; /* Index variable */
|
||||
float32_t f1, f2, d1, d2; /* Two nearest output values */
|
||||
int32_t n;
|
||||
float32_t findex, Dn, Df, temp;
|
||||
|
||||
/* input x is in degrees */
|
||||
/* Scale the input, divide input by 360, for cosine add 0.25 (pi/2) to read sine table */
|
||||
in = theta * 0.00277777777778f;
|
||||
|
||||
/* Calculation of floor value of input */
|
||||
n = (int32_t) in;
|
||||
|
||||
/* Make negative values towards -infinity */
|
||||
if(in < 0.0f)
|
||||
{
|
||||
n--;
|
||||
}
|
||||
/* Map input value to [0 1] */
|
||||
in = in - (float32_t) n;
|
||||
|
||||
/* Calculation of index of the table */
|
||||
findex = (float32_t) FAST_MATH_TABLE_SIZE * in;
|
||||
indexS = ((uint16_t)findex) & 0x1ff;
|
||||
indexC = (indexS + (FAST_MATH_TABLE_SIZE / 4)) & 0x1ff;
|
||||
|
||||
/* fractional value calculation */
|
||||
fract = findex - (float32_t) indexS;
|
||||
|
||||
/* Read two nearest values of input value from the cos & sin tables */
|
||||
f1 = sinTable_f32[indexC+0];
|
||||
f2 = sinTable_f32[indexC+1];
|
||||
d1 = -sinTable_f32[indexS+0];
|
||||
d2 = -sinTable_f32[indexS+1];
|
||||
|
||||
Dn = 0.0122718463030f; // delta between the two points (fixed), in this case 2*pi/FAST_MATH_TABLE_SIZE
|
||||
Df = f2 - f1; // delta between the values of the functions
|
||||
temp = Dn*(d1 + d2) - 2*Df;
|
||||
temp = fract*temp + (3*Df - (d2 + 2*d1)*Dn);
|
||||
temp = fract*temp + d1*Dn;
|
||||
|
||||
/* Calculation of cosine value */
|
||||
*pCosVal = fract*temp + f1;
|
||||
|
||||
/* Read two nearest values of input value from the cos & sin tables */
|
||||
f1 = sinTable_f32[indexS+0];
|
||||
f2 = sinTable_f32[indexS+1];
|
||||
d1 = sinTable_f32[indexC+0];
|
||||
d2 = sinTable_f32[indexC+1];
|
||||
|
||||
Df = f2 - f1; // delta between the values of the functions
|
||||
temp = Dn*(d1 + d2) - 2*Df;
|
||||
temp = fract*temp + (3*Df - (d2 + 2*d1)*Dn);
|
||||
temp = fract*temp + d1*Dn;
|
||||
|
||||
/* Calculation of sine value */
|
||||
*pSinVal = fract*temp + f1;
|
||||
}
|
||||
/**
|
||||
* @} end of SinCos group
|
||||
*/
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_sin_cos_q31.c
|
||||
*
|
||||
* Description: Cosine & Sine calculation for Q31 values.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_common_tables.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupController
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup SinCos
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q31 sin_cos function.
|
||||
* @param[in] theta scaled input value in degrees
|
||||
* @param[out] *pSinVal points to the processed sine output.
|
||||
* @param[out] *pCosVal points to the processed cosine output.
|
||||
* @return none.
|
||||
*
|
||||
* The Q31 input value is in the range [-1 0.999999] and is mapped to a degree value in the range [-180 179].
|
||||
*
|
||||
*/
|
||||
|
||||
void arm_sin_cos_q31(
|
||||
q31_t theta,
|
||||
q31_t * pSinVal,
|
||||
q31_t * pCosVal)
|
||||
{
|
||||
q31_t fract; /* Temporary variables for input, output */
|
||||
uint16_t indexS, indexC; /* Index variable */
|
||||
q31_t f1, f2, d1, d2; /* Two nearest output values */
|
||||
q31_t Dn, Df;
|
||||
q63_t temp;
|
||||
|
||||
/* Calculate the nearest index */
|
||||
indexS = (uint32_t)theta >> CONTROLLER_Q31_SHIFT;
|
||||
indexC = (indexS + 128) & 0x1ff;
|
||||
|
||||
/* Calculation of fractional value */
|
||||
fract = (theta - (indexS << CONTROLLER_Q31_SHIFT)) << 8;
|
||||
|
||||
/* Read two nearest values of input value from the cos & sin tables */
|
||||
f1 = sinTable_q31[indexC+0];
|
||||
f2 = sinTable_q31[indexC+1];
|
||||
d1 = -sinTable_q31[indexS+0];
|
||||
d2 = -sinTable_q31[indexS+1];
|
||||
|
||||
Dn = 0x1921FB5; // delta between the two points (fixed), in this case 2*pi/FAST_MATH_TABLE_SIZE
|
||||
Df = f2 - f1; // delta between the values of the functions
|
||||
temp = Dn*((q63_t)d1 + d2);
|
||||
temp = temp - ((q63_t)Df << 32);
|
||||
temp = (q63_t)fract*(temp >> 31);
|
||||
temp = temp + ((3*(q63_t)Df << 31) - (d2 + ((q63_t)d1 << 1))*Dn);
|
||||
temp = (q63_t)fract*(temp >> 31);
|
||||
temp = temp + (q63_t)d1*Dn;
|
||||
temp = (q63_t)fract*(temp >> 31);
|
||||
|
||||
/* Calculation of cosine value */
|
||||
*pCosVal = clip_q63_to_q31((temp >> 31) + (q63_t)f1);
|
||||
|
||||
/* Read two nearest values of input value from the cos & sin tables */
|
||||
f1 = sinTable_q31[indexS+0];
|
||||
f2 = sinTable_q31[indexS+1];
|
||||
d1 = sinTable_q31[indexC+0];
|
||||
d2 = sinTable_q31[indexC+1];
|
||||
|
||||
Df = f2 - f1; // delta between the values of the functions
|
||||
temp = Dn*((q63_t)d1 + d2);
|
||||
temp = temp - ((q63_t)Df << 32);
|
||||
temp = (q63_t)fract*(temp >> 31);
|
||||
temp = temp + ((3*(q63_t)Df << 31) - (d2 + ((q63_t)d1 << 1))*Dn);
|
||||
temp = (q63_t)fract*(temp >> 31);
|
||||
temp = temp + (q63_t)d1*Dn;
|
||||
temp = (q63_t)fract*(temp >> 31);
|
||||
|
||||
/* Calculation of sine value */
|
||||
*pSinVal = clip_q63_to_q31((temp >> 31) + (q63_t)f1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of SinCos group
|
||||
*/
|
||||
@@ -0,0 +1,127 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 21. September 2015
|
||||
* $Revision: V.1.4.5 a
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cos_f32.c
|
||||
*
|
||||
* Description: Fast cosine calculation for floating-point values.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_common_tables.h"
|
||||
/**
|
||||
* @ingroup groupFastMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup cos Cosine
|
||||
*
|
||||
* Computes the trigonometric cosine function using a combination of table lookup
|
||||
* and linear interpolation. There are separate functions for
|
||||
* Q15, Q31, and floating-point data types.
|
||||
* The input to the floating-point version is in radians while the
|
||||
* fixed-point Q15 and Q31 have a scaled input with the range
|
||||
* [0 +0.9999] mapping to [0 2*pi). The fixed-point range is chosen so that a
|
||||
* value of 2*pi wraps around to 0.
|
||||
*
|
||||
* The implementation is based on table lookup using 256 values together with linear interpolation.
|
||||
* The steps used are:
|
||||
* -# Calculation of the nearest integer table index
|
||||
* -# Compute the fractional portion (fract) of the table index.
|
||||
* -# The final result equals <code>(1.0f-fract)*a + fract*b;</code>
|
||||
*
|
||||
* where
|
||||
* <pre>
|
||||
* b=Table[index+0];
|
||||
* c=Table[index+1];
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup cos
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Fast approximation to the trigonometric cosine function for floating-point data.
|
||||
* @param[in] x input value in radians.
|
||||
* @return cos(x).
|
||||
*/
|
||||
|
||||
float32_t arm_cos_f32(
|
||||
float32_t x)
|
||||
{
|
||||
float32_t cosVal, fract, in; /* Temporary variables for input, output */
|
||||
uint16_t index; /* Index variable */
|
||||
float32_t a, b; /* Two nearest output values */
|
||||
int32_t n;
|
||||
float32_t findex;
|
||||
|
||||
/* input x is in radians */
|
||||
/* Scale the input to [0 1] range from [0 2*PI] , divide input by 2*pi, add 0.25 (pi/2) to read sine table */
|
||||
in = x * 0.159154943092f + 0.25f;
|
||||
|
||||
/* Calculation of floor value of input */
|
||||
n = (int32_t) in;
|
||||
|
||||
/* Make negative values towards -infinity */
|
||||
if(in < 0.0f)
|
||||
{
|
||||
n--;
|
||||
}
|
||||
|
||||
/* Map input value to [0 1] */
|
||||
in = in - (float32_t) n;
|
||||
|
||||
/* Calculation of index of the table */
|
||||
findex = (float32_t) FAST_MATH_TABLE_SIZE * in;
|
||||
index = ((uint16_t)findex) & 0x1ff;
|
||||
|
||||
/* fractional value calculation */
|
||||
fract = findex - (float32_t) index;
|
||||
|
||||
/* Read two nearest values of input value from the cos table */
|
||||
a = sinTable_f32[index];
|
||||
b = sinTable_f32[index+1];
|
||||
|
||||
/* Linear interpolation process */
|
||||
cosVal = (1.0f-fract)*a + fract*b;
|
||||
|
||||
/* Return the output value */
|
||||
return (cosVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of cos group
|
||||
*/
|
||||
@@ -0,0 +1,96 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 07. September 2015
|
||||
* $Revision: V.1.4.5 a
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cos_q15.c
|
||||
*
|
||||
* Description: Fast cosine calculation for Q15 values.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_common_tables.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupFastMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup cos
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Fast approximation to the trigonometric cosine function for Q15 data.
|
||||
* @param[in] x Scaled input value in radians.
|
||||
* @return cos(x).
|
||||
*
|
||||
* The Q15 input value is in the range [0 +0.9999] and is mapped to a radian
|
||||
* value in the range [0 2*pi).
|
||||
*/
|
||||
|
||||
q15_t arm_cos_q15(
|
||||
q15_t x)
|
||||
{
|
||||
q15_t cosVal; /* Temporary variables for input, output */
|
||||
int32_t index; /* Index variables */
|
||||
q15_t a, b; /* Four nearest output values */
|
||||
q15_t fract; /* Temporary values for fractional values */
|
||||
|
||||
/* add 0.25 (pi/2) to read sine table */
|
||||
x = (uint16_t)x + 0x2000;
|
||||
if(x < 0)
|
||||
{ /* convert negative numbers to corresponding positive ones */
|
||||
x = (uint16_t)x + 0x8000;
|
||||
}
|
||||
|
||||
/* Calculate the nearest index */
|
||||
index = (uint32_t)x >> FAST_MATH_Q15_SHIFT;
|
||||
|
||||
/* Calculation of fractional value */
|
||||
fract = (x - (index << FAST_MATH_Q15_SHIFT)) << 9;
|
||||
|
||||
/* Read two nearest values of input value from the sin table */
|
||||
a = sinTable_q15[index];
|
||||
b = sinTable_q15[index+1];
|
||||
|
||||
/* Linear interpolation process */
|
||||
cosVal = (q31_t)(0x8000-fract)*a >> 16;
|
||||
cosVal = (q15_t)((((q31_t)cosVal << 16) + ((q31_t)fract*b)) >> 16);
|
||||
|
||||
return cosVal << 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of cos group
|
||||
*/
|
||||
@@ -0,0 +1,96 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 07. September 2015
|
||||
* $Revision: V.1.4.5 a
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cos_q31.c
|
||||
*
|
||||
* Description: Fast cosine calculation for Q31 values.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_common_tables.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupFastMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup cos
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Fast approximation to the trigonometric cosine function for Q31 data.
|
||||
* @param[in] x Scaled input value in radians.
|
||||
* @return cos(x).
|
||||
*
|
||||
* The Q31 input value is in the range [0 +0.9999] and is mapped to a radian
|
||||
* value in the range [0 2*pi).
|
||||
*/
|
||||
|
||||
q31_t arm_cos_q31(
|
||||
q31_t x)
|
||||
{
|
||||
q31_t cosVal; /* Temporary variables for input, output */
|
||||
int32_t index; /* Index variables */
|
||||
q31_t a, b; /* Four nearest output values */
|
||||
q31_t fract; /* Temporary values for fractional values */
|
||||
|
||||
/* add 0.25 (pi/2) to read sine table */
|
||||
x = (uint32_t)x + 0x20000000;
|
||||
if(x < 0)
|
||||
{ /* convert negative numbers to corresponding positive ones */
|
||||
x = (uint32_t)x + 0x80000000;
|
||||
}
|
||||
|
||||
/* Calculate the nearest index */
|
||||
index = (uint32_t)x >> FAST_MATH_Q31_SHIFT;
|
||||
|
||||
/* Calculation of fractional value */
|
||||
fract = (x - (index << FAST_MATH_Q31_SHIFT)) << 9;
|
||||
|
||||
/* Read two nearest values of input value from the sin table */
|
||||
a = sinTable_q31[index];
|
||||
b = sinTable_q31[index+1];
|
||||
|
||||
/* Linear interpolation process */
|
||||
cosVal = (q63_t)(0x80000000-fract)*a >> 32;
|
||||
cosVal = (q31_t)((((q63_t)cosVal << 32) + ((q63_t)fract*b)) >> 32);
|
||||
|
||||
return cosVal << 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of cos group
|
||||
*/
|
||||
@@ -0,0 +1,133 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 21. September 2015
|
||||
* $Revision: V.1.4.5 a
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_sin_f32.c
|
||||
*
|
||||
* Description: Fast sine calculation for floating-point values.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_common_tables.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* @ingroup groupFastMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup sin Sine
|
||||
*
|
||||
* Computes the trigonometric sine function using a combination of table lookup
|
||||
* and linear interpolation. There are separate functions for
|
||||
* Q15, Q31, and floating-point data types.
|
||||
* The input to the floating-point version is in radians while the
|
||||
* fixed-point Q15 and Q31 have a scaled input with the range
|
||||
* [0 +0.9999] mapping to [0 2*pi). The fixed-point range is chosen so that a
|
||||
* value of 2*pi wraps around to 0.
|
||||
*
|
||||
* The implementation is based on table lookup using 256 values together with linear interpolation.
|
||||
* The steps used are:
|
||||
* -# Calculation of the nearest integer table index
|
||||
* -# Compute the fractional portion (fract) of the table index.
|
||||
* -# The final result equals <code>(1.0f-fract)*a + fract*b;</code>
|
||||
*
|
||||
* where
|
||||
* <pre>
|
||||
* b=Table[index+0];
|
||||
* c=Table[index+1];
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup sin
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Fast approximation to the trigonometric sine function for floating-point data.
|
||||
* @param[in] x input value in radians.
|
||||
* @return sin(x).
|
||||
*/
|
||||
|
||||
float32_t arm_sin_f32(
|
||||
float32_t x)
|
||||
{
|
||||
float32_t sinVal, fract, in; /* Temporary variables for input, output */
|
||||
uint16_t index; /* Index variable */
|
||||
float32_t a, b; /* Two nearest output values */
|
||||
int32_t n;
|
||||
float32_t findex;
|
||||
|
||||
/* input x is in radians */
|
||||
/* Scale the input to [0 1] range from [0 2*PI] , divide input by 2*pi */
|
||||
in = x * 0.159154943092f;
|
||||
|
||||
/* Calculation of floor value of input */
|
||||
n = (int32_t) in;
|
||||
|
||||
/* Make negative values towards -infinity */
|
||||
if(x < 0.0f)
|
||||
{
|
||||
n--;
|
||||
}
|
||||
|
||||
/* Map input value to [0 1] */
|
||||
in = in - (float32_t) n;
|
||||
|
||||
/* Calculation of index of the table */
|
||||
findex = (float32_t) FAST_MATH_TABLE_SIZE * in;
|
||||
if (findex >= 512.0f) {
|
||||
findex -= 512.0f;
|
||||
}
|
||||
|
||||
index = ((uint16_t)findex) & 0x1ff;
|
||||
|
||||
/* fractional value calculation */
|
||||
fract = findex - (float32_t) index;
|
||||
|
||||
/* Read two nearest values of input value from the sin table */
|
||||
a = sinTable_f32[index];
|
||||
b = sinTable_f32[index+1];
|
||||
|
||||
/* Linear interpolation process */
|
||||
sinVal = (1.0f-fract)*a + fract*b;
|
||||
|
||||
/* Return the output value */
|
||||
return (sinVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of sin group
|
||||
*/
|
||||
@@ -0,0 +1,88 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_sin_q15.c
|
||||
*
|
||||
* Description: Fast sine calculation for Q15 values.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_common_tables.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupFastMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup sin
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Fast approximation to the trigonometric sine function for Q15 data.
|
||||
* @param[in] x Scaled input value in radians.
|
||||
* @return sin(x).
|
||||
*
|
||||
* The Q15 input value is in the range [0 +0.9999] and is mapped to a radian value in the range [0 2*pi).
|
||||
*/
|
||||
|
||||
q15_t arm_sin_q15(
|
||||
q15_t x)
|
||||
{
|
||||
q15_t sinVal; /* Temporary variables for input, output */
|
||||
int32_t index; /* Index variables */
|
||||
q15_t a, b; /* Four nearest output values */
|
||||
q15_t fract; /* Temporary values for fractional values */
|
||||
|
||||
/* Calculate the nearest index */
|
||||
index = (uint32_t)x >> FAST_MATH_Q15_SHIFT;
|
||||
|
||||
/* Calculation of fractional value */
|
||||
fract = (x - (index << FAST_MATH_Q15_SHIFT)) << 9;
|
||||
|
||||
/* Read two nearest values of input value from the sin table */
|
||||
a = sinTable_q15[index];
|
||||
b = sinTable_q15[index+1];
|
||||
|
||||
/* Linear interpolation process */
|
||||
sinVal = (q31_t)(0x8000-fract)*a >> 16;
|
||||
sinVal = (q15_t)((((q31_t)sinVal << 16) + ((q31_t)fract*b)) >> 16);
|
||||
|
||||
return sinVal << 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of sin group
|
||||
*/
|
||||
@@ -0,0 +1,87 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_sin_q31.c
|
||||
*
|
||||
* Description: Fast sine calculation for Q31 values.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_common_tables.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupFastMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup sin
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Fast approximation to the trigonometric sine function for Q31 data.
|
||||
* @param[in] x Scaled input value in radians.
|
||||
* @return sin(x).
|
||||
*
|
||||
* The Q31 input value is in the range [0 +0.9999] and is mapped to a radian value in the range [0 2*pi). */
|
||||
|
||||
q31_t arm_sin_q31(
|
||||
q31_t x)
|
||||
{
|
||||
q31_t sinVal; /* Temporary variables for input, output */
|
||||
int32_t index; /* Index variables */
|
||||
q31_t a, b; /* Four nearest output values */
|
||||
q31_t fract; /* Temporary values for fractional values */
|
||||
|
||||
/* Calculate the nearest index */
|
||||
index = (uint32_t)x >> FAST_MATH_Q31_SHIFT;
|
||||
|
||||
/* Calculation of fractional value */
|
||||
fract = (x - (index << FAST_MATH_Q31_SHIFT)) << 9;
|
||||
|
||||
/* Read two nearest values of input value from the sin table */
|
||||
a = sinTable_q31[index];
|
||||
b = sinTable_q31[index+1];
|
||||
|
||||
/* Linear interpolation process */
|
||||
sinVal = (q63_t)(0x80000000-fract)*a >> 32;
|
||||
sinVal = (q31_t)((((q63_t)sinVal << 32) + ((q63_t)fract*b)) >> 32);
|
||||
|
||||
return sinVal << 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of sin group
|
||||
*/
|
||||
@@ -0,0 +1,155 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. October 2015
|
||||
* $Revision: V.1.4.5 a
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_sqrt_q15.c
|
||||
*
|
||||
* Description: Q15 square root function.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
#include "arm_math.h"
|
||||
#include "arm_common_tables.h"
|
||||
|
||||
|
||||
/**
|
||||
* @ingroup groupFastMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup SQRT
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q15 square root function.
|
||||
* @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF.
|
||||
* @param[out] *pOut square root of input value.
|
||||
* @return The function returns ARM_MATH_SUCCESS if the input value is positive
|
||||
* and ARM_MATH_ARGUMENT_ERROR if the input is negative. For
|
||||
* negative inputs, the function returns *pOut = 0.
|
||||
*/
|
||||
|
||||
arm_status arm_sqrt_q15(
|
||||
q15_t in,
|
||||
q15_t * pOut)
|
||||
{
|
||||
q15_t number, temp1, var1, signBits1, half;
|
||||
q31_t bits_val1;
|
||||
float32_t temp_float1;
|
||||
union
|
||||
{
|
||||
q31_t fracval;
|
||||
float32_t floatval;
|
||||
} tempconv;
|
||||
|
||||
number = in;
|
||||
|
||||
/* If the input is a positive number then compute the signBits. */
|
||||
if(number > 0)
|
||||
{
|
||||
signBits1 = __CLZ(number) - 17;
|
||||
|
||||
/* Shift by the number of signBits1 */
|
||||
if((signBits1 % 2) == 0)
|
||||
{
|
||||
number = number << signBits1;
|
||||
}
|
||||
else
|
||||
{
|
||||
number = number << (signBits1 - 1);
|
||||
}
|
||||
|
||||
/* Calculate half value of the number */
|
||||
half = number >> 1;
|
||||
/* Store the number for later use */
|
||||
temp1 = number;
|
||||
|
||||
/* Convert to float */
|
||||
temp_float1 = number * 3.051757812500000e-005f;
|
||||
/*Store as integer */
|
||||
tempconv.floatval = temp_float1;
|
||||
bits_val1 = tempconv.fracval;
|
||||
/* Subtract the shifted value from the magic number to give intial guess */
|
||||
bits_val1 = 0x5f3759df - (bits_val1 >> 1); /* gives initial guess */
|
||||
/* Store as float */
|
||||
tempconv.fracval = bits_val1;
|
||||
temp_float1 = tempconv.floatval;
|
||||
/* Convert to integer format */
|
||||
var1 = (q31_t) (temp_float1 * 16384);
|
||||
|
||||
/* 1st iteration */
|
||||
var1 = ((q15_t) ((q31_t) var1 * (0x3000 -
|
||||
((q15_t)
|
||||
((((q15_t)
|
||||
(((q31_t) var1 * var1) >> 15)) *
|
||||
(q31_t) half) >> 15))) >> 15)) << 2;
|
||||
/* 2nd iteration */
|
||||
var1 = ((q15_t) ((q31_t) var1 * (0x3000 -
|
||||
((q15_t)
|
||||
((((q15_t)
|
||||
(((q31_t) var1 * var1) >> 15)) *
|
||||
(q31_t) half) >> 15))) >> 15)) << 2;
|
||||
/* 3rd iteration */
|
||||
var1 = ((q15_t) ((q31_t) var1 * (0x3000 -
|
||||
((q15_t)
|
||||
((((q15_t)
|
||||
(((q31_t) var1 * var1) >> 15)) *
|
||||
(q31_t) half) >> 15))) >> 15)) << 2;
|
||||
|
||||
/* Multiply the inverse square root with the original value */
|
||||
var1 = ((q15_t) (((q31_t) temp1 * var1) >> 15)) << 1;
|
||||
|
||||
/* Shift the output down accordingly */
|
||||
if((signBits1 % 2) == 0)
|
||||
{
|
||||
var1 = var1 >> (signBits1 / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
var1 = var1 >> ((signBits1 - 1) / 2);
|
||||
}
|
||||
*pOut = var1;
|
||||
|
||||
return (ARM_MATH_SUCCESS);
|
||||
}
|
||||
/* If the number is a negative number then store zero as its square root value */
|
||||
else
|
||||
{
|
||||
*pOut = 0;
|
||||
return (ARM_MATH_ARGUMENT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of SQRT group
|
||||
*/
|
||||
@@ -0,0 +1,153 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. October 2015
|
||||
* $Revision: V.1.4.5 a
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_sqrt_q31.c
|
||||
*
|
||||
* Description: Q31 square root function.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
#include "arm_math.h"
|
||||
#include "arm_common_tables.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupFastMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup SQRT
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q31 square root function.
|
||||
* @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF.
|
||||
* @param[out] *pOut square root of input value.
|
||||
* @return The function returns ARM_MATH_SUCCESS if the input value is positive
|
||||
* and ARM_MATH_ARGUMENT_ERROR if the input is negative. For
|
||||
* negative inputs, the function returns *pOut = 0.
|
||||
*/
|
||||
|
||||
arm_status arm_sqrt_q31(
|
||||
q31_t in,
|
||||
q31_t * pOut)
|
||||
{
|
||||
q31_t number, temp1, bits_val1, var1, signBits1, half;
|
||||
float32_t temp_float1;
|
||||
union
|
||||
{
|
||||
q31_t fracval;
|
||||
float32_t floatval;
|
||||
} tempconv;
|
||||
|
||||
number = in;
|
||||
|
||||
/* If the input is a positive number then compute the signBits. */
|
||||
if(number > 0)
|
||||
{
|
||||
signBits1 = __CLZ(number) - 1;
|
||||
|
||||
/* Shift by the number of signBits1 */
|
||||
if((signBits1 % 2) == 0)
|
||||
{
|
||||
number = number << signBits1;
|
||||
}
|
||||
else
|
||||
{
|
||||
number = number << (signBits1 - 1);
|
||||
}
|
||||
|
||||
/* Calculate half value of the number */
|
||||
half = number >> 1;
|
||||
/* Store the number for later use */
|
||||
temp1 = number;
|
||||
|
||||
/*Convert to float */
|
||||
temp_float1 = number * 4.6566128731e-010f;
|
||||
/*Store as integer */
|
||||
tempconv.floatval = temp_float1;
|
||||
bits_val1 = tempconv.fracval;
|
||||
/* Subtract the shifted value from the magic number to give intial guess */
|
||||
bits_val1 = 0x5f3759df - (bits_val1 >> 1); /* gives initial guess */
|
||||
/* Store as float */
|
||||
tempconv.fracval = bits_val1;
|
||||
temp_float1 = tempconv.floatval;
|
||||
/* Convert to integer format */
|
||||
var1 = (q31_t) (temp_float1 * 1073741824);
|
||||
|
||||
/* 1st iteration */
|
||||
var1 = ((q31_t) ((q63_t) var1 * (0x30000000 -
|
||||
((q31_t)
|
||||
((((q31_t)
|
||||
(((q63_t) var1 * var1) >> 31)) *
|
||||
(q63_t) half) >> 31))) >> 31)) << 2;
|
||||
/* 2nd iteration */
|
||||
var1 = ((q31_t) ((q63_t) var1 * (0x30000000 -
|
||||
((q31_t)
|
||||
((((q31_t)
|
||||
(((q63_t) var1 * var1) >> 31)) *
|
||||
(q63_t) half) >> 31))) >> 31)) << 2;
|
||||
/* 3rd iteration */
|
||||
var1 = ((q31_t) ((q63_t) var1 * (0x30000000 -
|
||||
((q31_t)
|
||||
((((q31_t)
|
||||
(((q63_t) var1 * var1) >> 31)) *
|
||||
(q63_t) half) >> 31))) >> 31)) << 2;
|
||||
|
||||
/* Multiply the inverse square root with the original value */
|
||||
var1 = ((q31_t) (((q63_t) temp1 * var1) >> 31)) << 1;
|
||||
|
||||
/* Shift the output down accordingly */
|
||||
if((signBits1 % 2) == 0)
|
||||
{
|
||||
var1 = var1 >> (signBits1 / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
var1 = var1 >> ((signBits1 - 1) / 2);
|
||||
}
|
||||
*pOut = var1;
|
||||
|
||||
return (ARM_MATH_SUCCESS);
|
||||
}
|
||||
/* If the number is a negative number then store zero as its square root value */
|
||||
else
|
||||
{
|
||||
*pOut = 0;
|
||||
return (ARM_MATH_ARGUMENT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of SQRT group
|
||||
*/
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_biquad_cascade_df1_32x64_init_q31.c
|
||||
*
|
||||
* Description: High precision Q31 Biquad cascade filter initialization function.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupFilters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BiquadCascadeDF1_32x64
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @details
|
||||
*
|
||||
* @param[in,out] *S points to an instance of the high precision Q31 Biquad cascade filter structure.
|
||||
* @param[in] numStages number of 2nd order stages in the filter.
|
||||
* @param[in] *pCoeffs points to the filter coefficients.
|
||||
* @param[in] *pState points to the state buffer.
|
||||
* @param[in] postShift Shift to be applied after the accumulator. Varies according to the coefficients format.
|
||||
* @return none
|
||||
*
|
||||
* <b>Coefficient and State Ordering:</b>
|
||||
*
|
||||
* \par
|
||||
* The coefficients are stored in the array <code>pCoeffs</code> in the following order:
|
||||
* <pre>
|
||||
* {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
|
||||
* </pre>
|
||||
* where <code>b1x</code> and <code>a1x</code> are the coefficients for the first stage,
|
||||
* <code>b2x</code> and <code>a2x</code> are the coefficients for the second stage,
|
||||
* and so on. The <code>pCoeffs</code> array contains a total of <code>5*numStages</code> values.
|
||||
*
|
||||
* \par
|
||||
* The <code>pState</code> points to state variables array and size of each state variable is 1.63 format.
|
||||
* Each Biquad stage has 4 state variables <code>x[n-1], x[n-2], y[n-1],</code> and <code>y[n-2]</code>.
|
||||
* The state variables are arranged in the state array as:
|
||||
* <pre>
|
||||
* {x[n-1], x[n-2], y[n-1], y[n-2]}
|
||||
* </pre>
|
||||
* The 4 state variables for stage 1 are first, then the 4 state variables for stage 2, and so on.
|
||||
* The state array has a total length of <code>4*numStages</code> values.
|
||||
* The state variables are updated after each block of data is processed; the coefficients are untouched.
|
||||
*/
|
||||
|
||||
void arm_biquad_cas_df1_32x64_init_q31(
|
||||
arm_biquad_cas_df1_32x64_ins_q31 * S,
|
||||
uint8_t numStages,
|
||||
q31_t * pCoeffs,
|
||||
q63_t * pState,
|
||||
uint8_t postShift)
|
||||
{
|
||||
/* Assign filter stages */
|
||||
S->numStages = numStages;
|
||||
|
||||
/* Assign postShift to be applied to the output */
|
||||
S->postShift = postShift;
|
||||
|
||||
/* Assign coefficient pointer */
|
||||
S->pCoeffs = pCoeffs;
|
||||
|
||||
/* Clear state buffer and size is always 4 * numStages */
|
||||
memset(pState, 0, (4u * (uint32_t) numStages) * sizeof(q63_t));
|
||||
|
||||
/* Assign state pointer */
|
||||
S->pState = pState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BiquadCascadeDF1_32x64 group
|
||||
*/
|
||||
+561
@@ -0,0 +1,561 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. October 2015
|
||||
* $Revision: V.1.4.5 a
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_biquad_cascade_df1_32x64_q31.c
|
||||
*
|
||||
* Description: High precision Q31 Biquad cascade filter processing function
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupFilters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup BiquadCascadeDF1_32x64 High Precision Q31 Biquad Cascade Filter
|
||||
*
|
||||
* This function implements a high precision Biquad cascade filter which operates on
|
||||
* Q31 data values. The filter coefficients are in 1.31 format and the state variables
|
||||
* are in 1.63 format. The double precision state variables reduce quantization noise
|
||||
* in the filter and provide a cleaner output.
|
||||
* These filters are particularly useful when implementing filters in which the
|
||||
* singularities are close to the unit circle. This is common for low pass or high
|
||||
* pass filters with very low cutoff frequencies.
|
||||
*
|
||||
* The function operates on blocks of input and output data
|
||||
* and each call to the function processes <code>blockSize</code> samples through
|
||||
* the filter. <code>pSrc</code> and <code>pDst</code> points to input and output arrays
|
||||
* containing <code>blockSize</code> Q31 values.
|
||||
*
|
||||
* \par Algorithm
|
||||
* Each Biquad stage implements a second order filter using the difference equation:
|
||||
* <pre>
|
||||
* y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
|
||||
* </pre>
|
||||
* A Direct Form I algorithm is used with 5 coefficients and 4 state variables per stage.
|
||||
* \image html Biquad.gif "Single Biquad filter stage"
|
||||
* Coefficients <code>b0, b1, and b2 </code> multiply the input signal <code>x[n]</code> and are referred to as the feedforward coefficients.
|
||||
* Coefficients <code>a1</code> and <code>a2</code> multiply the output signal <code>y[n]</code> and are referred to as the feedback coefficients.
|
||||
* Pay careful attention to the sign of the feedback coefficients.
|
||||
* Some design tools use the difference equation
|
||||
* <pre>
|
||||
* y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] - a1 * y[n-1] - a2 * y[n-2]
|
||||
* </pre>
|
||||
* In this case the feedback coefficients <code>a1</code> and <code>a2</code> must be negated when used with the CMSIS DSP Library.
|
||||
*
|
||||
* \par
|
||||
* Higher order filters are realized as a cascade of second order sections.
|
||||
* <code>numStages</code> refers to the number of second order stages used.
|
||||
* For example, an 8th order filter would be realized with <code>numStages=4</code> second order stages.
|
||||
* \image html BiquadCascade.gif "8th order filter using a cascade of Biquad stages"
|
||||
* A 9th order filter would be realized with <code>numStages=5</code> second order stages with the coefficients for one of the stages configured as a first order filter (<code>b2=0</code> and <code>a2=0</code>).
|
||||
*
|
||||
* \par
|
||||
* The <code>pState</code> points to state variables array .
|
||||
* Each Biquad stage has 4 state variables <code>x[n-1], x[n-2], y[n-1],</code> and <code>y[n-2]</code> and each state variable in 1.63 format to improve precision.
|
||||
* The state variables are arranged in the array as:
|
||||
* <pre>
|
||||
* {x[n-1], x[n-2], y[n-1], y[n-2]}
|
||||
* </pre>
|
||||
*
|
||||
* \par
|
||||
* The 4 state variables for stage 1 are first, then the 4 state variables for stage 2, and so on.
|
||||
* The state array has a total length of <code>4*numStages</code> values of data in 1.63 format.
|
||||
* The state variables are updated after each block of data is processed; the coefficients are untouched.
|
||||
*
|
||||
* \par Instance Structure
|
||||
* The coefficients and state variables for a filter are stored together in an instance data structure.
|
||||
* A separate instance structure must be defined for each filter.
|
||||
* Coefficient arrays may be shared among several instances while state variable arrays cannot be shared.
|
||||
*
|
||||
* \par Init Function
|
||||
* There is also an associated initialization function which performs the following operations:
|
||||
* - Sets the values of the internal structure fields.
|
||||
* - Zeros out the values in the state buffer.
|
||||
* To do this manually without calling the init function, assign the follow subfields of the instance structure:
|
||||
* numStages, pCoeffs, postShift, pState. Also set all of the values in pState to zero.
|
||||
*
|
||||
* \par
|
||||
* Use of the initialization function is optional.
|
||||
* However, if the initialization function is used, then the instance structure cannot be placed into a const data section.
|
||||
* To place an instance structure into a const data section, the instance structure must be manually initialized.
|
||||
* Set the values in the state buffer to zeros before static initialization.
|
||||
* For example, to statically initialize the filter instance structure use
|
||||
* <pre>
|
||||
* arm_biquad_cas_df1_32x64_ins_q31 S1 = {numStages, pState, pCoeffs, postShift};
|
||||
* </pre>
|
||||
* where <code>numStages</code> is the number of Biquad stages in the filter; <code>pState</code> is the address of the state buffer;
|
||||
* <code>pCoeffs</code> is the address of the coefficient buffer; <code>postShift</code> shift to be applied which is described in detail below.
|
||||
* \par Fixed-Point Behavior
|
||||
* Care must be taken while using Biquad Cascade 32x64 filter function.
|
||||
* Following issues must be considered:
|
||||
* - Scaling of coefficients
|
||||
* - Filter gain
|
||||
* - Overflow and saturation
|
||||
*
|
||||
* \par
|
||||
* Filter coefficients are represented as fractional values and
|
||||
* restricted to lie in the range <code>[-1 +1)</code>.
|
||||
* The processing function has an additional scaling parameter <code>postShift</code>
|
||||
* which allows the filter coefficients to exceed the range <code>[+1 -1)</code>.
|
||||
* At the output of the filter's accumulator is a shift register which shifts the result by <code>postShift</code> bits.
|
||||
* \image html BiquadPostshift.gif "Fixed-point Biquad with shift by postShift bits after accumulator"
|
||||
* This essentially scales the filter coefficients by <code>2^postShift</code>.
|
||||
* For example, to realize the coefficients
|
||||
* <pre>
|
||||
* {1.5, -0.8, 1.2, 1.6, -0.9}
|
||||
* </pre>
|
||||
* set the Coefficient array to:
|
||||
* <pre>
|
||||
* {0.75, -0.4, 0.6, 0.8, -0.45}
|
||||
* </pre>
|
||||
* and set <code>postShift=1</code>
|
||||
*
|
||||
* \par
|
||||
* The second thing to keep in mind is the gain through the filter.
|
||||
* The frequency response of a Biquad filter is a function of its coefficients.
|
||||
* It is possible for the gain through the filter to exceed 1.0 meaning that the filter increases the amplitude of certain frequencies.
|
||||
* This means that an input signal with amplitude < 1.0 may result in an output > 1.0 and these are saturated or overflowed based on the implementation of the filter.
|
||||
* To avoid this behavior the filter needs to be scaled down such that its peak gain < 1.0 or the input signal must be scaled down so that the combination of input and filter are never overflowed.
|
||||
*
|
||||
* \par
|
||||
* The third item to consider is the overflow and saturation behavior of the fixed-point Q31 version.
|
||||
* This is described in the function specific documentation below.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BiquadCascadeDF1_32x64
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @details
|
||||
|
||||
* @param[in] *S points to an instance of the high precision Q31 Biquad cascade filter.
|
||||
* @param[in] *pSrc points to the block of input data.
|
||||
* @param[out] *pDst points to the block of output data.
|
||||
* @param[in] blockSize number of samples to process.
|
||||
* @return none.
|
||||
*
|
||||
* \par
|
||||
* The function is implemented using an internal 64-bit accumulator.
|
||||
* The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit.
|
||||
* Thus, if the accumulator result overflows it wraps around rather than clip.
|
||||
* In order to avoid overflows completely the input signal must be scaled down by 2 bits and lie in the range [-0.25 +0.25).
|
||||
* After all 5 multiply-accumulates are performed, the 2.62 accumulator is shifted by <code>postShift</code> bits and the result truncated to
|
||||
* 1.31 format by discarding the low 32 bits.
|
||||
*
|
||||
* \par
|
||||
* Two related functions are provided in the CMSIS DSP library.
|
||||
* <code>arm_biquad_cascade_df1_q31()</code> implements a Biquad cascade with 32-bit coefficients and state variables with a Q63 accumulator.
|
||||
* <code>arm_biquad_cascade_df1_fast_q31()</code> implements a Biquad cascade with 32-bit coefficients and state variables with a Q31 accumulator.
|
||||
*/
|
||||
|
||||
void arm_biquad_cas_df1_32x64_q31(
|
||||
const arm_biquad_cas_df1_32x64_ins_q31 * S,
|
||||
q31_t * pSrc,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
q31_t *pIn = pSrc; /* input pointer initialization */
|
||||
q31_t *pOut = pDst; /* output pointer initialization */
|
||||
q63_t *pState = S->pState; /* state pointer initialization */
|
||||
q31_t *pCoeffs = S->pCoeffs; /* coeff pointer initialization */
|
||||
q63_t acc; /* accumulator */
|
||||
q31_t Xn1, Xn2; /* Input Filter state variables */
|
||||
q63_t Yn1, Yn2; /* Output Filter state variables */
|
||||
q31_t b0, b1, b2, a1, a2; /* Filter coefficients */
|
||||
q31_t Xn; /* temporary input */
|
||||
int32_t shift = (int32_t) S->postShift + 1; /* Shift to be applied to the output */
|
||||
uint32_t sample, stage = S->numStages; /* loop counters */
|
||||
q31_t acc_l, acc_h; /* temporary output */
|
||||
uint32_t uShift = ((uint32_t) S->postShift + 1u);
|
||||
uint32_t lShift = 32u - uShift; /* Shift to be applied to the output */
|
||||
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
do
|
||||
{
|
||||
/* Reading the coefficients */
|
||||
b0 = *pCoeffs++;
|
||||
b1 = *pCoeffs++;
|
||||
b2 = *pCoeffs++;
|
||||
a1 = *pCoeffs++;
|
||||
a2 = *pCoeffs++;
|
||||
|
||||
/* Reading the state values */
|
||||
Xn1 = (q31_t) (pState[0]);
|
||||
Xn2 = (q31_t) (pState[1]);
|
||||
Yn1 = pState[2];
|
||||
Yn2 = pState[3];
|
||||
|
||||
/* Apply loop unrolling and compute 4 output values simultaneously. */
|
||||
/* The variable acc hold output value that is being computed and
|
||||
* stored in the destination buffer
|
||||
* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
|
||||
*/
|
||||
|
||||
sample = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(sample > 0u)
|
||||
{
|
||||
/* Read the input */
|
||||
Xn = *pIn++;
|
||||
|
||||
/* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
|
||||
|
||||
/* acc = b0 * x[n] */
|
||||
acc = (q63_t) Xn *b0;
|
||||
|
||||
/* acc += b1 * x[n-1] */
|
||||
acc += (q63_t) Xn1 *b1;
|
||||
|
||||
/* acc += b[2] * x[n-2] */
|
||||
acc += (q63_t) Xn2 *b2;
|
||||
|
||||
/* acc += a1 * y[n-1] */
|
||||
acc += mult32x64(Yn1, a1);
|
||||
|
||||
/* acc += a2 * y[n-2] */
|
||||
acc += mult32x64(Yn2, a2);
|
||||
|
||||
/* The result is converted to 1.63 , Yn2 variable is reused */
|
||||
Yn2 = acc << shift;
|
||||
|
||||
/* Calc lower part of acc */
|
||||
acc_l = acc & 0xffffffff;
|
||||
|
||||
/* Calc upper part of acc */
|
||||
acc_h = (acc >> 32) & 0xffffffff;
|
||||
|
||||
/* Apply shift for lower part of acc and upper part of acc */
|
||||
acc_h = (uint32_t) acc_l >> lShift | acc_h << uShift;
|
||||
|
||||
/* Store the output in the destination buffer in 1.31 format. */
|
||||
*pOut = acc_h;
|
||||
|
||||
/* Read the second input into Xn2, to reuse the value */
|
||||
Xn2 = *pIn++;
|
||||
|
||||
/* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
|
||||
|
||||
/* acc += b1 * x[n-1] */
|
||||
acc = (q63_t) Xn *b1;
|
||||
|
||||
/* acc = b0 * x[n] */
|
||||
acc += (q63_t) Xn2 *b0;
|
||||
|
||||
/* acc += b[2] * x[n-2] */
|
||||
acc += (q63_t) Xn1 *b2;
|
||||
|
||||
/* acc += a1 * y[n-1] */
|
||||
acc += mult32x64(Yn2, a1);
|
||||
|
||||
/* acc += a2 * y[n-2] */
|
||||
acc += mult32x64(Yn1, a2);
|
||||
|
||||
/* The result is converted to 1.63, Yn1 variable is reused */
|
||||
Yn1 = acc << shift;
|
||||
|
||||
/* Calc lower part of acc */
|
||||
acc_l = acc & 0xffffffff;
|
||||
|
||||
/* Calc upper part of acc */
|
||||
acc_h = (acc >> 32) & 0xffffffff;
|
||||
|
||||
/* Apply shift for lower part of acc and upper part of acc */
|
||||
acc_h = (uint32_t) acc_l >> lShift | acc_h << uShift;
|
||||
|
||||
/* Read the third input into Xn1, to reuse the value */
|
||||
Xn1 = *pIn++;
|
||||
|
||||
/* The result is converted to 1.31 */
|
||||
/* Store the output in the destination buffer. */
|
||||
*(pOut + 1u) = acc_h;
|
||||
|
||||
/* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
|
||||
|
||||
/* acc = b0 * x[n] */
|
||||
acc = (q63_t) Xn1 *b0;
|
||||
|
||||
/* acc += b1 * x[n-1] */
|
||||
acc += (q63_t) Xn2 *b1;
|
||||
|
||||
/* acc += b[2] * x[n-2] */
|
||||
acc += (q63_t) Xn *b2;
|
||||
|
||||
/* acc += a1 * y[n-1] */
|
||||
acc += mult32x64(Yn1, a1);
|
||||
|
||||
/* acc += a2 * y[n-2] */
|
||||
acc += mult32x64(Yn2, a2);
|
||||
|
||||
/* The result is converted to 1.63, Yn2 variable is reused */
|
||||
Yn2 = acc << shift;
|
||||
|
||||
/* Calc lower part of acc */
|
||||
acc_l = acc & 0xffffffff;
|
||||
|
||||
/* Calc upper part of acc */
|
||||
acc_h = (acc >> 32) & 0xffffffff;
|
||||
|
||||
/* Apply shift for lower part of acc and upper part of acc */
|
||||
acc_h = (uint32_t) acc_l >> lShift | acc_h << uShift;
|
||||
|
||||
/* Store the output in the destination buffer in 1.31 format. */
|
||||
*(pOut + 2u) = acc_h;
|
||||
|
||||
/* Read the fourth input into Xn, to reuse the value */
|
||||
Xn = *pIn++;
|
||||
|
||||
/* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
|
||||
/* acc = b0 * x[n] */
|
||||
acc = (q63_t) Xn *b0;
|
||||
|
||||
/* acc += b1 * x[n-1] */
|
||||
acc += (q63_t) Xn1 *b1;
|
||||
|
||||
/* acc += b[2] * x[n-2] */
|
||||
acc += (q63_t) Xn2 *b2;
|
||||
|
||||
/* acc += a1 * y[n-1] */
|
||||
acc += mult32x64(Yn2, a1);
|
||||
|
||||
/* acc += a2 * y[n-2] */
|
||||
acc += mult32x64(Yn1, a2);
|
||||
|
||||
/* The result is converted to 1.63, Yn1 variable is reused */
|
||||
Yn1 = acc << shift;
|
||||
|
||||
/* Calc lower part of acc */
|
||||
acc_l = acc & 0xffffffff;
|
||||
|
||||
/* Calc upper part of acc */
|
||||
acc_h = (acc >> 32) & 0xffffffff;
|
||||
|
||||
/* Apply shift for lower part of acc and upper part of acc */
|
||||
acc_h = (uint32_t) acc_l >> lShift | acc_h << uShift;
|
||||
|
||||
/* Store the output in the destination buffer in 1.31 format. */
|
||||
*(pOut + 3u) = acc_h;
|
||||
|
||||
/* Every time after the output is computed state should be updated. */
|
||||
/* The states should be updated as: */
|
||||
/* Xn2 = Xn1 */
|
||||
/* Xn1 = Xn */
|
||||
/* Yn2 = Yn1 */
|
||||
/* Yn1 = acc */
|
||||
Xn2 = Xn1;
|
||||
Xn1 = Xn;
|
||||
|
||||
/* update output pointer */
|
||||
pOut += 4u;
|
||||
|
||||
/* decrement the loop counter */
|
||||
sample--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
sample = (blockSize & 0x3u);
|
||||
|
||||
while(sample > 0u)
|
||||
{
|
||||
/* Read the input */
|
||||
Xn = *pIn++;
|
||||
|
||||
/* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
|
||||
|
||||
/* acc = b0 * x[n] */
|
||||
acc = (q63_t) Xn *b0;
|
||||
/* acc += b1 * x[n-1] */
|
||||
acc += (q63_t) Xn1 *b1;
|
||||
/* acc += b[2] * x[n-2] */
|
||||
acc += (q63_t) Xn2 *b2;
|
||||
/* acc += a1 * y[n-1] */
|
||||
acc += mult32x64(Yn1, a1);
|
||||
/* acc += a2 * y[n-2] */
|
||||
acc += mult32x64(Yn2, a2);
|
||||
|
||||
/* Every time after the output is computed state should be updated. */
|
||||
/* The states should be updated as: */
|
||||
/* Xn2 = Xn1 */
|
||||
/* Xn1 = Xn */
|
||||
/* Yn2 = Yn1 */
|
||||
/* Yn1 = acc */
|
||||
Xn2 = Xn1;
|
||||
Xn1 = Xn;
|
||||
Yn2 = Yn1;
|
||||
/* The result is converted to 1.63, Yn1 variable is reused */
|
||||
Yn1 = acc << shift;
|
||||
|
||||
/* Calc lower part of acc */
|
||||
acc_l = acc & 0xffffffff;
|
||||
|
||||
/* Calc upper part of acc */
|
||||
acc_h = (acc >> 32) & 0xffffffff;
|
||||
|
||||
/* Apply shift for lower part of acc and upper part of acc */
|
||||
acc_h = (uint32_t) acc_l >> lShift | acc_h << uShift;
|
||||
|
||||
/* Store the output in the destination buffer in 1.31 format. */
|
||||
*pOut++ = acc_h;
|
||||
/* Yn1 = acc << shift; */
|
||||
|
||||
/* Store the output in the destination buffer in 1.31 format. */
|
||||
/* *pOut++ = (q31_t) (acc >> (32 - shift)); */
|
||||
|
||||
/* decrement the loop counter */
|
||||
sample--;
|
||||
}
|
||||
|
||||
/* The first stage output is given as input to the second stage. */
|
||||
pIn = pDst;
|
||||
|
||||
/* Reset to destination buffer working pointer */
|
||||
pOut = pDst;
|
||||
|
||||
/* Store the updated state variables back into the pState array */
|
||||
/* Store the updated state variables back into the pState array */
|
||||
*pState++ = (q63_t) Xn1;
|
||||
*pState++ = (q63_t) Xn2;
|
||||
*pState++ = Yn1;
|
||||
*pState++ = Yn2;
|
||||
|
||||
} while(--stage);
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
do
|
||||
{
|
||||
/* Reading the coefficients */
|
||||
b0 = *pCoeffs++;
|
||||
b1 = *pCoeffs++;
|
||||
b2 = *pCoeffs++;
|
||||
a1 = *pCoeffs++;
|
||||
a2 = *pCoeffs++;
|
||||
|
||||
/* Reading the state values */
|
||||
Xn1 = pState[0];
|
||||
Xn2 = pState[1];
|
||||
Yn1 = pState[2];
|
||||
Yn2 = pState[3];
|
||||
|
||||
/* The variable acc hold output value that is being computed and
|
||||
* stored in the destination buffer
|
||||
* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
|
||||
*/
|
||||
|
||||
sample = blockSize;
|
||||
|
||||
while(sample > 0u)
|
||||
{
|
||||
/* Read the input */
|
||||
Xn = *pIn++;
|
||||
|
||||
/* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
|
||||
/* acc = b0 * x[n] */
|
||||
acc = (q63_t) Xn *b0;
|
||||
/* acc += b1 * x[n-1] */
|
||||
acc += (q63_t) Xn1 *b1;
|
||||
/* acc += b[2] * x[n-2] */
|
||||
acc += (q63_t) Xn2 *b2;
|
||||
/* acc += a1 * y[n-1] */
|
||||
acc += mult32x64(Yn1, a1);
|
||||
/* acc += a2 * y[n-2] */
|
||||
acc += mult32x64(Yn2, a2);
|
||||
|
||||
/* Every time after the output is computed state should be updated. */
|
||||
/* The states should be updated as: */
|
||||
/* Xn2 = Xn1 */
|
||||
/* Xn1 = Xn */
|
||||
/* Yn2 = Yn1 */
|
||||
/* Yn1 = acc */
|
||||
Xn2 = Xn1;
|
||||
Xn1 = Xn;
|
||||
Yn2 = Yn1;
|
||||
|
||||
/* The result is converted to 1.63, Yn1 variable is reused */
|
||||
Yn1 = acc << shift;
|
||||
|
||||
/* Calc lower part of acc */
|
||||
acc_l = acc & 0xffffffff;
|
||||
|
||||
/* Calc upper part of acc */
|
||||
acc_h = (acc >> 32) & 0xffffffff;
|
||||
|
||||
/* Apply shift for lower part of acc and upper part of acc */
|
||||
acc_h = (uint32_t) acc_l >> lShift | acc_h << uShift;
|
||||
|
||||
/* Store the output in the destination buffer in 1.31 format. */
|
||||
*pOut++ = acc_h;
|
||||
|
||||
/* Yn1 = acc << shift; */
|
||||
|
||||
/* Store the output in the destination buffer in 1.31 format. */
|
||||
/* *pOut++ = (q31_t) (acc >> (32 - shift)); */
|
||||
|
||||
/* decrement the loop counter */
|
||||
sample--;
|
||||
}
|
||||
|
||||
/* The first stage output is given as input to the second stage. */
|
||||
pIn = pDst;
|
||||
|
||||
/* Reset to destination buffer working pointer */
|
||||
pOut = pDst;
|
||||
|
||||
/* Store the updated state variables back into the pState array */
|
||||
*pState++ = (q63_t) Xn1;
|
||||
*pState++ = (q63_t) Xn2;
|
||||
*pState++ = Yn1;
|
||||
*pState++ = Yn2;
|
||||
|
||||
} while(--stage);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BiquadCascadeDF1_32x64 group
|
||||
*/
|
||||
+425
@@ -0,0 +1,425 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_biquad_cascade_df1_f32.c
|
||||
*
|
||||
* Description: Processing function for the
|
||||
* floating-point Biquad cascade DirectFormI(DF1) filter.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupFilters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup BiquadCascadeDF1 Biquad Cascade IIR Filters Using Direct Form I Structure
|
||||
*
|
||||
* This set of functions implements arbitrary order recursive (IIR) filters.
|
||||
* The filters are implemented as a cascade of second order Biquad sections.
|
||||
* The functions support Q15, Q31 and floating-point data types.
|
||||
* Fast version of Q15 and Q31 also supported on CortexM4 and Cortex-M3.
|
||||
*
|
||||
* The functions operate on blocks of input and output data and each call to the function
|
||||
* processes <code>blockSize</code> samples through the filter.
|
||||
* <code>pSrc</code> points to the array of input data and
|
||||
* <code>pDst</code> points to the array of output data.
|
||||
* Both arrays contain <code>blockSize</code> values.
|
||||
*
|
||||
* \par Algorithm
|
||||
* Each Biquad stage implements a second order filter using the difference equation:
|
||||
* <pre>
|
||||
* y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
|
||||
* </pre>
|
||||
* A Direct Form I algorithm is used with 5 coefficients and 4 state variables per stage.
|
||||
* \image html Biquad.gif "Single Biquad filter stage"
|
||||
* Coefficients <code>b0, b1 and b2 </code> multiply the input signal <code>x[n]</code> and are referred to as the feedforward coefficients.
|
||||
* Coefficients <code>a1</code> and <code>a2</code> multiply the output signal <code>y[n]</code> and are referred to as the feedback coefficients.
|
||||
* Pay careful attention to the sign of the feedback coefficients.
|
||||
* Some design tools use the difference equation
|
||||
* <pre>
|
||||
* y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] - a1 * y[n-1] - a2 * y[n-2]
|
||||
* </pre>
|
||||
* In this case the feedback coefficients <code>a1</code> and <code>a2</code> must be negated when used with the CMSIS DSP Library.
|
||||
*
|
||||
* \par
|
||||
* Higher order filters are realized as a cascade of second order sections.
|
||||
* <code>numStages</code> refers to the number of second order stages used.
|
||||
* For example, an 8th order filter would be realized with <code>numStages=4</code> second order stages.
|
||||
* \image html BiquadCascade.gif "8th order filter using a cascade of Biquad stages"
|
||||
* A 9th order filter would be realized with <code>numStages=5</code> second order stages with the coefficients for one of the stages configured as a first order filter (<code>b2=0</code> and <code>a2=0</code>).
|
||||
*
|
||||
* \par
|
||||
* The <code>pState</code> points to state variables array.
|
||||
* Each Biquad stage has 4 state variables <code>x[n-1], x[n-2], y[n-1],</code> and <code>y[n-2]</code>.
|
||||
* The state variables are arranged in the <code>pState</code> array as:
|
||||
* <pre>
|
||||
* {x[n-1], x[n-2], y[n-1], y[n-2]}
|
||||
* </pre>
|
||||
*
|
||||
* \par
|
||||
* The 4 state variables for stage 1 are first, then the 4 state variables for stage 2, and so on.
|
||||
* The state array has a total length of <code>4*numStages</code> values.
|
||||
* The state variables are updated after each block of data is processed, the coefficients are untouched.
|
||||
*
|
||||
* \par Instance Structure
|
||||
* The coefficients and state variables for a filter are stored together in an instance data structure.
|
||||
* A separate instance structure must be defined for each filter.
|
||||
* Coefficient arrays may be shared among several instances while state variable arrays cannot be shared.
|
||||
* There are separate instance structure declarations for each of the 3 supported data types.
|
||||
*
|
||||
* \par Init Functions
|
||||
* There is also an associated initialization function for each data type.
|
||||
* The initialization function performs following operations:
|
||||
* - Sets the values of the internal structure fields.
|
||||
* - Zeros out the values in the state buffer.
|
||||
* To do this manually without calling the init function, assign the follow subfields of the instance structure:
|
||||
* numStages, pCoeffs, pState. Also set all of the values in pState to zero.
|
||||
*
|
||||
* \par
|
||||
* Use of the initialization function is optional.
|
||||
* However, if the initialization function is used, then the instance structure cannot be placed into a const data section.
|
||||
* To place an instance structure into a const data section, the instance structure must be manually initialized.
|
||||
* Set the values in the state buffer to zeros before static initialization.
|
||||
* The code below statically initializes each of the 3 different data type filter instance structures
|
||||
* <pre>
|
||||
* arm_biquad_casd_df1_inst_f32 S1 = {numStages, pState, pCoeffs};
|
||||
* arm_biquad_casd_df1_inst_q15 S2 = {numStages, pState, pCoeffs, postShift};
|
||||
* arm_biquad_casd_df1_inst_q31 S3 = {numStages, pState, pCoeffs, postShift};
|
||||
* </pre>
|
||||
* where <code>numStages</code> is the number of Biquad stages in the filter; <code>pState</code> is the address of the state buffer;
|
||||
* <code>pCoeffs</code> is the address of the coefficient buffer; <code>postShift</code> shift to be applied.
|
||||
*
|
||||
* \par Fixed-Point Behavior
|
||||
* Care must be taken when using the Q15 and Q31 versions of the Biquad Cascade filter functions.
|
||||
* Following issues must be considered:
|
||||
* - Scaling of coefficients
|
||||
* - Filter gain
|
||||
* - Overflow and saturation
|
||||
*
|
||||
* \par
|
||||
* <b>Scaling of coefficients: </b>
|
||||
* Filter coefficients are represented as fractional values and
|
||||
* coefficients are restricted to lie in the range <code>[-1 +1)</code>.
|
||||
* The fixed-point functions have an additional scaling parameter <code>postShift</code>
|
||||
* which allow the filter coefficients to exceed the range <code>[+1 -1)</code>.
|
||||
* At the output of the filter's accumulator is a shift register which shifts the result by <code>postShift</code> bits.
|
||||
* \image html BiquadPostshift.gif "Fixed-point Biquad with shift by postShift bits after accumulator"
|
||||
* This essentially scales the filter coefficients by <code>2^postShift</code>.
|
||||
* For example, to realize the coefficients
|
||||
* <pre>
|
||||
* {1.5, -0.8, 1.2, 1.6, -0.9}
|
||||
* </pre>
|
||||
* set the pCoeffs array to:
|
||||
* <pre>
|
||||
* {0.75, -0.4, 0.6, 0.8, -0.45}
|
||||
* </pre>
|
||||
* and set <code>postShift=1</code>
|
||||
*
|
||||
* \par
|
||||
* <b>Filter gain: </b>
|
||||
* The frequency response of a Biquad filter is a function of its coefficients.
|
||||
* It is possible for the gain through the filter to exceed 1.0 meaning that the filter increases the amplitude of certain frequencies.
|
||||
* This means that an input signal with amplitude < 1.0 may result in an output > 1.0 and these are saturated or overflowed based on the implementation of the filter.
|
||||
* To avoid this behavior the filter needs to be scaled down such that its peak gain < 1.0 or the input signal must be scaled down so that the combination of input and filter are never overflowed.
|
||||
*
|
||||
* \par
|
||||
* <b>Overflow and saturation: </b>
|
||||
* For Q15 and Q31 versions, it is described separately as part of the function specific documentation below.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BiquadCascadeDF1
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param[in] *S points to an instance of the floating-point Biquad cascade structure.
|
||||
* @param[in] *pSrc points to the block of input data.
|
||||
* @param[out] *pDst points to the block of output data.
|
||||
* @param[in] blockSize number of samples to process per call.
|
||||
* @return none.
|
||||
*
|
||||
*/
|
||||
|
||||
void arm_biquad_cascade_df1_f32(
|
||||
const arm_biquad_casd_df1_inst_f32 * S,
|
||||
float32_t * pSrc,
|
||||
float32_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
float32_t *pIn = pSrc; /* source pointer */
|
||||
float32_t *pOut = pDst; /* destination pointer */
|
||||
float32_t *pState = S->pState; /* pState pointer */
|
||||
float32_t *pCoeffs = S->pCoeffs; /* coefficient pointer */
|
||||
float32_t acc; /* Simulates the accumulator */
|
||||
float32_t b0, b1, b2, a1, a2; /* Filter coefficients */
|
||||
float32_t Xn1, Xn2, Yn1, Yn2; /* Filter pState variables */
|
||||
float32_t Xn; /* temporary input */
|
||||
uint32_t sample, stage = S->numStages; /* loop counters */
|
||||
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
do
|
||||
{
|
||||
/* Reading the coefficients */
|
||||
b0 = *pCoeffs++;
|
||||
b1 = *pCoeffs++;
|
||||
b2 = *pCoeffs++;
|
||||
a1 = *pCoeffs++;
|
||||
a2 = *pCoeffs++;
|
||||
|
||||
/* Reading the pState values */
|
||||
Xn1 = pState[0];
|
||||
Xn2 = pState[1];
|
||||
Yn1 = pState[2];
|
||||
Yn2 = pState[3];
|
||||
|
||||
/* Apply loop unrolling and compute 4 output values simultaneously. */
|
||||
/* The variable acc hold output values that are being computed:
|
||||
*
|
||||
* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
|
||||
* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
|
||||
* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
|
||||
* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
|
||||
*/
|
||||
|
||||
sample = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(sample > 0u)
|
||||
{
|
||||
/* Read the first input */
|
||||
Xn = *pIn++;
|
||||
|
||||
/* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
|
||||
Yn2 = (b0 * Xn) + (b1 * Xn1) + (b2 * Xn2) + (a1 * Yn1) + (a2 * Yn2);
|
||||
|
||||
/* Store the result in the accumulator in the destination buffer. */
|
||||
*pOut++ = Yn2;
|
||||
|
||||
/* Every time after the output is computed state should be updated. */
|
||||
/* The states should be updated as: */
|
||||
/* Xn2 = Xn1 */
|
||||
/* Xn1 = Xn */
|
||||
/* Yn2 = Yn1 */
|
||||
/* Yn1 = acc */
|
||||
|
||||
/* Read the second input */
|
||||
Xn2 = *pIn++;
|
||||
|
||||
/* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
|
||||
Yn1 = (b0 * Xn2) + (b1 * Xn) + (b2 * Xn1) + (a1 * Yn2) + (a2 * Yn1);
|
||||
|
||||
/* Store the result in the accumulator in the destination buffer. */
|
||||
*pOut++ = Yn1;
|
||||
|
||||
/* Every time after the output is computed state should be updated. */
|
||||
/* The states should be updated as: */
|
||||
/* Xn2 = Xn1 */
|
||||
/* Xn1 = Xn */
|
||||
/* Yn2 = Yn1 */
|
||||
/* Yn1 = acc */
|
||||
|
||||
/* Read the third input */
|
||||
Xn1 = *pIn++;
|
||||
|
||||
/* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
|
||||
Yn2 = (b0 * Xn1) + (b1 * Xn2) + (b2 * Xn) + (a1 * Yn1) + (a2 * Yn2);
|
||||
|
||||
/* Store the result in the accumulator in the destination buffer. */
|
||||
*pOut++ = Yn2;
|
||||
|
||||
/* Every time after the output is computed state should be updated. */
|
||||
/* The states should be updated as: */
|
||||
/* Xn2 = Xn1 */
|
||||
/* Xn1 = Xn */
|
||||
/* Yn2 = Yn1 */
|
||||
/* Yn1 = acc */
|
||||
|
||||
/* Read the forth input */
|
||||
Xn = *pIn++;
|
||||
|
||||
/* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
|
||||
Yn1 = (b0 * Xn) + (b1 * Xn1) + (b2 * Xn2) + (a1 * Yn2) + (a2 * Yn1);
|
||||
|
||||
/* Store the result in the accumulator in the destination buffer. */
|
||||
*pOut++ = Yn1;
|
||||
|
||||
/* Every time after the output is computed state should be updated. */
|
||||
/* The states should be updated as: */
|
||||
/* Xn2 = Xn1 */
|
||||
/* Xn1 = Xn */
|
||||
/* Yn2 = Yn1 */
|
||||
/* Yn1 = acc */
|
||||
Xn2 = Xn1;
|
||||
Xn1 = Xn;
|
||||
|
||||
/* decrement the loop counter */
|
||||
sample--;
|
||||
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
sample = blockSize & 0x3u;
|
||||
|
||||
while(sample > 0u)
|
||||
{
|
||||
/* Read the input */
|
||||
Xn = *pIn++;
|
||||
|
||||
/* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
|
||||
acc = (b0 * Xn) + (b1 * Xn1) + (b2 * Xn2) + (a1 * Yn1) + (a2 * Yn2);
|
||||
|
||||
/* Store the result in the accumulator in the destination buffer. */
|
||||
*pOut++ = acc;
|
||||
|
||||
/* Every time after the output is computed state should be updated. */
|
||||
/* The states should be updated as: */
|
||||
/* Xn2 = Xn1 */
|
||||
/* Xn1 = Xn */
|
||||
/* Yn2 = Yn1 */
|
||||
/* Yn1 = acc */
|
||||
Xn2 = Xn1;
|
||||
Xn1 = Xn;
|
||||
Yn2 = Yn1;
|
||||
Yn1 = acc;
|
||||
|
||||
/* decrement the loop counter */
|
||||
sample--;
|
||||
|
||||
}
|
||||
|
||||
/* Store the updated state variables back into the pState array */
|
||||
*pState++ = Xn1;
|
||||
*pState++ = Xn2;
|
||||
*pState++ = Yn1;
|
||||
*pState++ = Yn2;
|
||||
|
||||
/* The first stage goes from the input buffer to the output buffer. */
|
||||
/* Subsequent numStages occur in-place in the output buffer */
|
||||
pIn = pDst;
|
||||
|
||||
/* Reset the output pointer */
|
||||
pOut = pDst;
|
||||
|
||||
/* decrement the loop counter */
|
||||
stage--;
|
||||
|
||||
} while(stage > 0u);
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
do
|
||||
{
|
||||
/* Reading the coefficients */
|
||||
b0 = *pCoeffs++;
|
||||
b1 = *pCoeffs++;
|
||||
b2 = *pCoeffs++;
|
||||
a1 = *pCoeffs++;
|
||||
a2 = *pCoeffs++;
|
||||
|
||||
/* Reading the pState values */
|
||||
Xn1 = pState[0];
|
||||
Xn2 = pState[1];
|
||||
Yn1 = pState[2];
|
||||
Yn2 = pState[3];
|
||||
|
||||
/* The variables acc holds the output value that is computed:
|
||||
* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
|
||||
*/
|
||||
|
||||
sample = blockSize;
|
||||
|
||||
while(sample > 0u)
|
||||
{
|
||||
/* Read the input */
|
||||
Xn = *pIn++;
|
||||
|
||||
/* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
|
||||
acc = (b0 * Xn) + (b1 * Xn1) + (b2 * Xn2) + (a1 * Yn1) + (a2 * Yn2);
|
||||
|
||||
/* Store the result in the accumulator in the destination buffer. */
|
||||
*pOut++ = acc;
|
||||
|
||||
/* Every time after the output is computed state should be updated. */
|
||||
/* The states should be updated as: */
|
||||
/* Xn2 = Xn1 */
|
||||
/* Xn1 = Xn */
|
||||
/* Yn2 = Yn1 */
|
||||
/* Yn1 = acc */
|
||||
Xn2 = Xn1;
|
||||
Xn1 = Xn;
|
||||
Yn2 = Yn1;
|
||||
Yn1 = acc;
|
||||
|
||||
/* decrement the loop counter */
|
||||
sample--;
|
||||
}
|
||||
|
||||
/* Store the updated state variables back into the pState array */
|
||||
*pState++ = Xn1;
|
||||
*pState++ = Xn2;
|
||||
*pState++ = Yn1;
|
||||
*pState++ = Yn2;
|
||||
|
||||
/* The first stage goes from the input buffer to the output buffer. */
|
||||
/* Subsequent numStages occur in-place in the output buffer */
|
||||
pIn = pDst;
|
||||
|
||||
/* Reset the output pointer */
|
||||
pOut = pDst;
|
||||
|
||||
/* decrement the loop counter */
|
||||
stage--;
|
||||
|
||||
} while(stage > 0u);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @} end of BiquadCascadeDF1 group
|
||||
*/
|
||||
+286
@@ -0,0 +1,286 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_biquad_cascade_df1_fast_q15.c
|
||||
*
|
||||
* Description: Fast processing function for the
|
||||
* Q15 Biquad cascade filter.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupFilters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BiquadCascadeDF1
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @details
|
||||
* @param[in] *S points to an instance of the Q15 Biquad cascade structure.
|
||||
* @param[in] *pSrc points to the block of input data.
|
||||
* @param[out] *pDst points to the block of output data.
|
||||
* @param[in] blockSize number of samples to process per call.
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* This fast version uses a 32-bit accumulator with 2.30 format.
|
||||
* The accumulator maintains full precision of the intermediate multiplication results but provides only a single guard bit.
|
||||
* Thus, if the accumulator result overflows it wraps around and distorts the result.
|
||||
* In order to avoid overflows completely the input signal must be scaled down by two bits and lie in the range [-0.25 +0.25).
|
||||
* The 2.30 accumulator is then shifted by <code>postShift</code> bits and the result truncated to 1.15 format by discarding the low 16 bits.
|
||||
*
|
||||
* \par
|
||||
* Refer to the function <code>arm_biquad_cascade_df1_q15()</code> for a slower implementation of this function which uses 64-bit accumulation to avoid wrap around distortion. Both the slow and the fast versions use the same instance structure.
|
||||
* Use the function <code>arm_biquad_cascade_df1_init_q15()</code> to initialize the filter structure.
|
||||
*
|
||||
*/
|
||||
|
||||
void arm_biquad_cascade_df1_fast_q15(
|
||||
const arm_biquad_casd_df1_inst_q15 * S,
|
||||
q15_t * pSrc,
|
||||
q15_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
q15_t *pIn = pSrc; /* Source pointer */
|
||||
q15_t *pOut = pDst; /* Destination pointer */
|
||||
q31_t in; /* Temporary variable to hold input value */
|
||||
q31_t out; /* Temporary variable to hold output value */
|
||||
q31_t b0; /* Temporary variable to hold bo value */
|
||||
q31_t b1, a1; /* Filter coefficients */
|
||||
q31_t state_in, state_out; /* Filter state variables */
|
||||
q31_t acc; /* Accumulator */
|
||||
int32_t shift = (int32_t) (15 - S->postShift); /* Post shift */
|
||||
q15_t *pState = S->pState; /* State pointer */
|
||||
q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
|
||||
uint32_t sample, stage = S->numStages; /* Stage loop counter */
|
||||
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
|
||||
/* Read the b0 and 0 coefficients using SIMD */
|
||||
b0 = *__SIMD32(pCoeffs)++;
|
||||
|
||||
/* Read the b1 and b2 coefficients using SIMD */
|
||||
b1 = *__SIMD32(pCoeffs)++;
|
||||
|
||||
/* Read the a1 and a2 coefficients using SIMD */
|
||||
a1 = *__SIMD32(pCoeffs)++;
|
||||
|
||||
/* Read the input state values from the state buffer: x[n-1], x[n-2] */
|
||||
state_in = *__SIMD32(pState)++;
|
||||
|
||||
/* Read the output state values from the state buffer: y[n-1], y[n-2] */
|
||||
state_out = *__SIMD32(pState)--;
|
||||
|
||||
/* Apply loop unrolling and compute 2 output values simultaneously. */
|
||||
/* The variable acc hold output values that are being computed:
|
||||
*
|
||||
* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
|
||||
* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
|
||||
*/
|
||||
sample = blockSize >> 1u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 2 outputs at a time.
|
||||
** a second loop below computes the remaining 1 sample. */
|
||||
while(sample > 0u)
|
||||
{
|
||||
|
||||
/* Read the input */
|
||||
in = *__SIMD32(pIn)++;
|
||||
|
||||
/* out = b0 * x[n] + 0 * 0 */
|
||||
out = __SMUAD(b0, in);
|
||||
/* acc = b1 * x[n-1] + acc += b2 * x[n-2] + out */
|
||||
acc = __SMLAD(b1, state_in, out);
|
||||
/* acc += a1 * y[n-1] + acc += a2 * y[n-2] */
|
||||
acc = __SMLAD(a1, state_out, acc);
|
||||
|
||||
/* The result is converted from 3.29 to 1.31 and then saturation is applied */
|
||||
out = __SSAT((acc >> shift), 16);
|
||||
|
||||
/* Every time after the output is computed state should be updated. */
|
||||
/* The states should be updated as: */
|
||||
/* Xn2 = Xn1 */
|
||||
/* Xn1 = Xn */
|
||||
/* Yn2 = Yn1 */
|
||||
/* Yn1 = acc */
|
||||
/* x[n-N], x[n-N-1] are packed together to make state_in of type q31 */
|
||||
/* y[n-N], y[n-N-1] are packed together to make state_out of type q31 */
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
state_in = __PKHBT(in, state_in, 16);
|
||||
state_out = __PKHBT(out, state_out, 16);
|
||||
|
||||
#else
|
||||
|
||||
state_in = __PKHBT(state_in >> 16, (in >> 16), 16);
|
||||
state_out = __PKHBT(state_out >> 16, (out), 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* out = b0 * x[n] + 0 * 0 */
|
||||
out = __SMUADX(b0, in);
|
||||
/* acc0 = b1 * x[n-1] , acc0 += b2 * x[n-2] + out */
|
||||
acc = __SMLAD(b1, state_in, out);
|
||||
/* acc += a1 * y[n-1] + acc += a2 * y[n-2] */
|
||||
acc = __SMLAD(a1, state_out, acc);
|
||||
|
||||
/* The result is converted from 3.29 to 1.31 and then saturation is applied */
|
||||
out = __SSAT((acc >> shift), 16);
|
||||
|
||||
|
||||
/* Store the output in the destination buffer. */
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*__SIMD32(pOut)++ = __PKHBT(state_out, out, 16);
|
||||
|
||||
#else
|
||||
|
||||
*__SIMD32(pOut)++ = __PKHBT(out, state_out >> 16, 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Every time after the output is computed state should be updated. */
|
||||
/* The states should be updated as: */
|
||||
/* Xn2 = Xn1 */
|
||||
/* Xn1 = Xn */
|
||||
/* Yn2 = Yn1 */
|
||||
/* Yn1 = acc */
|
||||
/* x[n-N], x[n-N-1] are packed together to make state_in of type q31 */
|
||||
/* y[n-N], y[n-N-1] are packed together to make state_out of type q31 */
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
state_in = __PKHBT(in >> 16, state_in, 16);
|
||||
state_out = __PKHBT(out, state_out, 16);
|
||||
|
||||
#else
|
||||
|
||||
state_in = __PKHBT(state_in >> 16, in, 16);
|
||||
state_out = __PKHBT(state_out >> 16, out, 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
|
||||
/* Decrement the loop counter */
|
||||
sample--;
|
||||
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 2, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
|
||||
if((blockSize & 0x1u) != 0u)
|
||||
{
|
||||
/* Read the input */
|
||||
in = *pIn++;
|
||||
|
||||
/* out = b0 * x[n] + 0 * 0 */
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
out = __SMUAD(b0, in);
|
||||
|
||||
#else
|
||||
|
||||
out = __SMUADX(b0, in);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* acc = b1 * x[n-1], acc += b2 * x[n-2] + out */
|
||||
acc = __SMLAD(b1, state_in, out);
|
||||
/* acc += a1 * y[n-1] + acc += a2 * y[n-2] */
|
||||
acc = __SMLAD(a1, state_out, acc);
|
||||
|
||||
/* The result is converted from 3.29 to 1.31 and then saturation is applied */
|
||||
out = __SSAT((acc >> shift), 16);
|
||||
|
||||
/* Store the output in the destination buffer. */
|
||||
*pOut++ = (q15_t) out;
|
||||
|
||||
/* Every time after the output is computed state should be updated. */
|
||||
/* The states should be updated as: */
|
||||
/* Xn2 = Xn1 */
|
||||
/* Xn1 = Xn */
|
||||
/* Yn2 = Yn1 */
|
||||
/* Yn1 = acc */
|
||||
/* x[n-N], x[n-N-1] are packed together to make state_in of type q31 */
|
||||
/* y[n-N], y[n-N-1] are packed together to make state_out of type q31 */
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
state_in = __PKHBT(in, state_in, 16);
|
||||
state_out = __PKHBT(out, state_out, 16);
|
||||
|
||||
#else
|
||||
|
||||
state_in = __PKHBT(state_in >> 16, in, 16);
|
||||
state_out = __PKHBT(state_out >> 16, out, 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
}
|
||||
|
||||
/* The first stage goes from the input buffer to the output buffer. */
|
||||
/* Subsequent (numStages - 1) occur in-place in the output buffer */
|
||||
pIn = pDst;
|
||||
|
||||
/* Reset the output pointer */
|
||||
pOut = pDst;
|
||||
|
||||
/* Store the updated state variables back into the state array */
|
||||
*__SIMD32(pState)++ = state_in;
|
||||
*__SIMD32(pState)++ = state_out;
|
||||
|
||||
|
||||
/* Decrement the loop counter */
|
||||
stage--;
|
||||
|
||||
} while(stage > 0u);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @} end of BiquadCascadeDF1 group
|
||||
*/
|
||||
+305
@@ -0,0 +1,305 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. October 2015
|
||||
* $Revision: V.1.4.5 a
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_biquad_cascade_df1_fast_q31.c
|
||||
*
|
||||
* Description: Processing function for the
|
||||
* Q31 Fast Biquad cascade DirectFormI(DF1) filter.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupFilters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BiquadCascadeDF1
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @details
|
||||
*
|
||||
* @param[in] *S points to an instance of the Q31 Biquad cascade structure.
|
||||
* @param[in] *pSrc points to the block of input data.
|
||||
* @param[out] *pDst points to the block of output data.
|
||||
* @param[in] blockSize number of samples to process per call.
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* This function is optimized for speed at the expense of fixed-point precision and overflow protection.
|
||||
* The result of each 1.31 x 1.31 multiplication is truncated to 2.30 format.
|
||||
* These intermediate results are added to a 2.30 accumulator.
|
||||
* Finally, the accumulator is saturated and converted to a 1.31 result.
|
||||
* The fast version has the same overflow behavior as the standard version and provides less precision since it discards the low 32 bits of each multiplication result.
|
||||
* In order to avoid overflows completely the input signal must be scaled down by two bits and lie in the range [-0.25 +0.25). Use the intialization function
|
||||
* arm_biquad_cascade_df1_init_q31() to initialize filter structure.
|
||||
*
|
||||
* \par
|
||||
* Refer to the function <code>arm_biquad_cascade_df1_q31()</code> for a slower implementation of this function which uses 64-bit accumulation to provide higher precision. Both the slow and the fast versions use the same instance structure.
|
||||
* Use the function <code>arm_biquad_cascade_df1_init_q31()</code> to initialize the filter structure.
|
||||
*/
|
||||
|
||||
void arm_biquad_cascade_df1_fast_q31(
|
||||
const arm_biquad_casd_df1_inst_q31 * S,
|
||||
q31_t * pSrc,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
q31_t acc = 0; /* accumulator */
|
||||
q31_t Xn1, Xn2, Yn1, Yn2; /* Filter state variables */
|
||||
q31_t b0, b1, b2, a1, a2; /* Filter coefficients */
|
||||
q31_t *pIn = pSrc; /* input pointer initialization */
|
||||
q31_t *pOut = pDst; /* output pointer initialization */
|
||||
q31_t *pState = S->pState; /* pState pointer initialization */
|
||||
q31_t *pCoeffs = S->pCoeffs; /* coeff pointer initialization */
|
||||
q31_t Xn; /* temporary input */
|
||||
int32_t shift = (int32_t) S->postShift + 1; /* Shift to be applied to the output */
|
||||
uint32_t sample, stage = S->numStages; /* loop counters */
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
/* Reading the coefficients */
|
||||
b0 = *pCoeffs++;
|
||||
b1 = *pCoeffs++;
|
||||
b2 = *pCoeffs++;
|
||||
a1 = *pCoeffs++;
|
||||
a2 = *pCoeffs++;
|
||||
|
||||
/* Reading the state values */
|
||||
Xn1 = pState[0];
|
||||
Xn2 = pState[1];
|
||||
Yn1 = pState[2];
|
||||
Yn2 = pState[3];
|
||||
|
||||
/* Apply loop unrolling and compute 4 output values simultaneously. */
|
||||
/* The variables acc ... acc3 hold output values that are being computed:
|
||||
*
|
||||
* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
|
||||
*/
|
||||
|
||||
sample = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(sample > 0u)
|
||||
{
|
||||
/* Read the input */
|
||||
Xn = *pIn;
|
||||
|
||||
/* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
|
||||
/* acc = b0 * x[n] */
|
||||
/*acc = (q31_t) (((q63_t) b1 * Xn1) >> 32);*/
|
||||
mult_32x32_keep32_R(acc, b1, Xn1);
|
||||
/* acc += b1 * x[n-1] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b0 * (Xn))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, b0, Xn);
|
||||
/* acc += b[2] * x[n-2] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b2 * (Xn2))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, b2, Xn2);
|
||||
/* acc += a1 * y[n-1] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a1 * (Yn1))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, a1, Yn1);
|
||||
/* acc += a2 * y[n-2] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a2 * (Yn2))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, a2, Yn2);
|
||||
|
||||
/* The result is converted to 1.31 , Yn2 variable is reused */
|
||||
Yn2 = acc << shift;
|
||||
|
||||
/* Read the second input */
|
||||
Xn2 = *(pIn + 1u);
|
||||
|
||||
/* Store the output in the destination buffer. */
|
||||
*pOut = Yn2;
|
||||
|
||||
/* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
|
||||
/* acc = b0 * x[n] */
|
||||
/*acc = (q31_t) (((q63_t) b0 * (Xn2)) >> 32);*/
|
||||
mult_32x32_keep32_R(acc, b0, Xn2);
|
||||
/* acc += b1 * x[n-1] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b1 * (Xn))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, b1, Xn);
|
||||
/* acc += b[2] * x[n-2] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b2 * (Xn1))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, b2, Xn1);
|
||||
/* acc += a1 * y[n-1] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a1 * (Yn2))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, a1, Yn2);
|
||||
/* acc += a2 * y[n-2] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a2 * (Yn1))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, a2, Yn1);
|
||||
|
||||
/* The result is converted to 1.31, Yn1 variable is reused */
|
||||
Yn1 = acc << shift;
|
||||
|
||||
/* Read the third input */
|
||||
Xn1 = *(pIn + 2u);
|
||||
|
||||
/* Store the output in the destination buffer. */
|
||||
*(pOut + 1u) = Yn1;
|
||||
|
||||
/* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
|
||||
/* acc = b0 * x[n] */
|
||||
/*acc = (q31_t) (((q63_t) b0 * (Xn1)) >> 32);*/
|
||||
mult_32x32_keep32_R(acc, b0, Xn1);
|
||||
/* acc += b1 * x[n-1] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b1 * (Xn2))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, b1, Xn2);
|
||||
/* acc += b[2] * x[n-2] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b2 * (Xn))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, b2, Xn);
|
||||
/* acc += a1 * y[n-1] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a1 * (Yn1))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, a1, Yn1);
|
||||
/* acc += a2 * y[n-2] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a2 * (Yn2))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, a2, Yn2);
|
||||
|
||||
/* The result is converted to 1.31, Yn2 variable is reused */
|
||||
Yn2 = acc << shift;
|
||||
|
||||
/* Read the forth input */
|
||||
Xn = *(pIn + 3u);
|
||||
|
||||
/* Store the output in the destination buffer. */
|
||||
*(pOut + 2u) = Yn2;
|
||||
pIn += 4u;
|
||||
|
||||
/* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
|
||||
/* acc = b0 * x[n] */
|
||||
/*acc = (q31_t) (((q63_t) b0 * (Xn)) >> 32);*/
|
||||
mult_32x32_keep32_R(acc, b0, Xn);
|
||||
/* acc += b1 * x[n-1] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b1 * (Xn1))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, b1, Xn1);
|
||||
/* acc += b[2] * x[n-2] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b2 * (Xn2))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, b2, Xn2);
|
||||
/* acc += a1 * y[n-1] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a1 * (Yn2))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, a1, Yn2);
|
||||
/* acc += a2 * y[n-2] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a2 * (Yn1))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, a2, Yn1);
|
||||
|
||||
/* Every time after the output is computed state should be updated. */
|
||||
/* The states should be updated as: */
|
||||
/* Xn2 = Xn1 */
|
||||
Xn2 = Xn1;
|
||||
|
||||
/* The result is converted to 1.31, Yn1 variable is reused */
|
||||
Yn1 = acc << shift;
|
||||
|
||||
/* Xn1 = Xn */
|
||||
Xn1 = Xn;
|
||||
|
||||
/* Store the output in the destination buffer. */
|
||||
*(pOut + 3u) = Yn1;
|
||||
pOut += 4u;
|
||||
|
||||
/* decrement the loop counter */
|
||||
sample--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
sample = (blockSize & 0x3u);
|
||||
|
||||
while(sample > 0u)
|
||||
{
|
||||
/* Read the input */
|
||||
Xn = *pIn++;
|
||||
|
||||
/* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
|
||||
/* acc = b0 * x[n] */
|
||||
/*acc = (q31_t) (((q63_t) b0 * (Xn)) >> 32);*/
|
||||
mult_32x32_keep32_R(acc, b0, Xn);
|
||||
/* acc += b1 * x[n-1] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b1 * (Xn1))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, b1, Xn1);
|
||||
/* acc += b[2] * x[n-2] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b2 * (Xn2))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, b2, Xn2);
|
||||
/* acc += a1 * y[n-1] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a1 * (Yn1))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, a1, Yn1);
|
||||
/* acc += a2 * y[n-2] */
|
||||
/*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a2 * (Yn2))) >> 32);*/
|
||||
multAcc_32x32_keep32_R(acc, a2, Yn2);
|
||||
|
||||
/* The result is converted to 1.31 */
|
||||
acc = acc << shift;
|
||||
|
||||
/* Every time after the output is computed state should be updated. */
|
||||
/* The states should be updated as: */
|
||||
/* Xn2 = Xn1 */
|
||||
/* Xn1 = Xn */
|
||||
/* Yn2 = Yn1 */
|
||||
/* Yn1 = acc */
|
||||
Xn2 = Xn1;
|
||||
Xn1 = Xn;
|
||||
Yn2 = Yn1;
|
||||
Yn1 = acc;
|
||||
|
||||
/* Store the output in the destination buffer. */
|
||||
*pOut++ = acc;
|
||||
|
||||
/* decrement the loop counter */
|
||||
sample--;
|
||||
}
|
||||
|
||||
/* The first stage goes from the input buffer to the output buffer. */
|
||||
/* Subsequent stages occur in-place in the output buffer */
|
||||
pIn = pDst;
|
||||
|
||||
/* Reset to destination pointer */
|
||||
pOut = pDst;
|
||||
|
||||
/* Store the updated state variables back into the pState array */
|
||||
*pState++ = Xn1;
|
||||
*pState++ = Xn2;
|
||||
*pState++ = Yn1;
|
||||
*pState++ = Yn2;
|
||||
|
||||
} while(--stage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BiquadCascadeDF1 group
|
||||
*/
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_biquad_cascade_df1_init_f32.c
|
||||
*
|
||||
* Description: floating-point Biquad cascade DirectFormI(DF1) filter initialization function.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------*/
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupFilters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BiquadCascadeDF1
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @details
|
||||
* @brief Initialization function for the floating-point Biquad cascade filter.
|
||||
* @param[in,out] *S points to an instance of the floating-point Biquad cascade structure.
|
||||
* @param[in] numStages number of 2nd order stages in the filter.
|
||||
* @param[in] *pCoeffs points to the filter coefficients array.
|
||||
* @param[in] *pState points to the state array.
|
||||
* @return none
|
||||
*
|
||||
*
|
||||
* <b>Coefficient and State Ordering:</b>
|
||||
*
|
||||
* \par
|
||||
* The coefficients are stored in the array <code>pCoeffs</code> in the following order:
|
||||
* <pre>
|
||||
* {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
|
||||
* </pre>
|
||||
*
|
||||
* \par
|
||||
* where <code>b1x</code> and <code>a1x</code> are the coefficients for the first stage,
|
||||
* <code>b2x</code> and <code>a2x</code> are the coefficients for the second stage,
|
||||
* and so on. The <code>pCoeffs</code> array contains a total of <code>5*numStages</code> values.
|
||||
*
|
||||
* \par
|
||||
* The <code>pState</code> is a pointer to state array.
|
||||
* Each Biquad stage has 4 state variables <code>x[n-1], x[n-2], y[n-1],</code> and <code>y[n-2]</code>.
|
||||
* The state variables are arranged in the <code>pState</code> array as:
|
||||
* <pre>
|
||||
* {x[n-1], x[n-2], y[n-1], y[n-2]}
|
||||
* </pre>
|
||||
* The 4 state variables for stage 1 are first, then the 4 state variables for stage 2, and so on.
|
||||
* The state array has a total length of <code>4*numStages</code> values.
|
||||
* The state variables are updated after each block of data is processed; the coefficients are untouched.
|
||||
*
|
||||
*/
|
||||
|
||||
void arm_biquad_cascade_df1_init_f32(
|
||||
arm_biquad_casd_df1_inst_f32 * S,
|
||||
uint8_t numStages,
|
||||
float32_t * pCoeffs,
|
||||
float32_t * pState)
|
||||
{
|
||||
/* Assign filter stages */
|
||||
S->numStages = numStages;
|
||||
|
||||
/* Assign coefficient pointer */
|
||||
S->pCoeffs = pCoeffs;
|
||||
|
||||
/* Clear state buffer and size is always 4 * numStages */
|
||||
memset(pState, 0, (4u * (uint32_t) numStages) * sizeof(float32_t));
|
||||
|
||||
/* Assign state pointer */
|
||||
S->pState = pState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BiquadCascadeDF1 group
|
||||
*/
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_biquad_cascade_df1_init_q15.c
|
||||
*
|
||||
* Description: Q15 Biquad cascade DirectFormI(DF1) filter initialization function.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------*/
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupFilters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BiquadCascadeDF1
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @details
|
||||
*
|
||||
* @param[in,out] *S points to an instance of the Q15 Biquad cascade structure.
|
||||
* @param[in] numStages number of 2nd order stages in the filter.
|
||||
* @param[in] *pCoeffs points to the filter coefficients.
|
||||
* @param[in] *pState points to the state buffer.
|
||||
* @param[in] postShift Shift to be applied to the accumulator result. Varies according to the coefficients format
|
||||
* @return none
|
||||
*
|
||||
* <b>Coefficient and State Ordering:</b>
|
||||
*
|
||||
* \par
|
||||
* The coefficients are stored in the array <code>pCoeffs</code> in the following order:
|
||||
* <pre>
|
||||
* {b10, 0, b11, b12, a11, a12, b20, 0, b21, b22, a21, a22, ...}
|
||||
* </pre>
|
||||
* where <code>b1x</code> and <code>a1x</code> are the coefficients for the first stage,
|
||||
* <code>b2x</code> and <code>a2x</code> are the coefficients for the second stage,
|
||||
* and so on. The <code>pCoeffs</code> array contains a total of <code>6*numStages</code> values.
|
||||
* The zero coefficient between <code>b1</code> and <code>b2</code> facilities use of 16-bit SIMD instructions on the Cortex-M4.
|
||||
*
|
||||
* \par
|
||||
* The state variables are stored in the array <code>pState</code>.
|
||||
* Each Biquad stage has 4 state variables <code>x[n-1], x[n-2], y[n-1],</code> and <code>y[n-2]</code>.
|
||||
* The state variables are arranged in the <code>pState</code> array as:
|
||||
* <pre>
|
||||
* {x[n-1], x[n-2], y[n-1], y[n-2]}
|
||||
* </pre>
|
||||
* The 4 state variables for stage 1 are first, then the 4 state variables for stage 2, and so on.
|
||||
* The state array has a total length of <code>4*numStages</code> values.
|
||||
* The state variables are updated after each block of data is processed; the coefficients are untouched.
|
||||
*/
|
||||
|
||||
void arm_biquad_cascade_df1_init_q15(
|
||||
arm_biquad_casd_df1_inst_q15 * S,
|
||||
uint8_t numStages,
|
||||
q15_t * pCoeffs,
|
||||
q15_t * pState,
|
||||
int8_t postShift)
|
||||
{
|
||||
/* Assign filter stages */
|
||||
S->numStages = numStages;
|
||||
|
||||
/* Assign postShift to be applied to the output */
|
||||
S->postShift = postShift;
|
||||
|
||||
/* Assign coefficient pointer */
|
||||
S->pCoeffs = pCoeffs;
|
||||
|
||||
/* Clear state buffer and size is always 4 * numStages */
|
||||
memset(pState, 0, (4u * (uint32_t) numStages) * sizeof(q15_t));
|
||||
|
||||
/* Assign state pointer */
|
||||
S->pState = pState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BiquadCascadeDF1 group
|
||||
*/
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_biquad_cascade_df1_init_q31.c
|
||||
*
|
||||
* Description: Q31 Biquad cascade DirectFormI(DF1) filter initialization function.
|
||||
*
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupFilters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BiquadCascadeDF1
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @details
|
||||
*
|
||||
* @param[in,out] *S points to an instance of the Q31 Biquad cascade structure.
|
||||
* @param[in] numStages number of 2nd order stages in the filter.
|
||||
* @param[in] *pCoeffs points to the filter coefficients buffer.
|
||||
* @param[in] *pState points to the state buffer.
|
||||
* @param[in] postShift Shift to be applied after the accumulator. Varies according to the coefficients format
|
||||
* @return none
|
||||
*
|
||||
* <b>Coefficient and State Ordering:</b>
|
||||
*
|
||||
* \par
|
||||
* The coefficients are stored in the array <code>pCoeffs</code> in the following order:
|
||||
* <pre>
|
||||
* {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
|
||||
* </pre>
|
||||
* where <code>b1x</code> and <code>a1x</code> are the coefficients for the first stage,
|
||||
* <code>b2x</code> and <code>a2x</code> are the coefficients for the second stage,
|
||||
* and so on. The <code>pCoeffs</code> array contains a total of <code>5*numStages</code> values.
|
||||
*
|
||||
* \par
|
||||
* The <code>pState</code> points to state variables array.
|
||||
* Each Biquad stage has 4 state variables <code>x[n-1], x[n-2], y[n-1],</code> and <code>y[n-2]</code>.
|
||||
* The state variables are arranged in the <code>pState</code> array as:
|
||||
* <pre>
|
||||
* {x[n-1], x[n-2], y[n-1], y[n-2]}
|
||||
* </pre>
|
||||
* The 4 state variables for stage 1 are first, then the 4 state variables for stage 2, and so on.
|
||||
* The state array has a total length of <code>4*numStages</code> values.
|
||||
* The state variables are updated after each block of data is processed; the coefficients are untouched.
|
||||
*/
|
||||
|
||||
void arm_biquad_cascade_df1_init_q31(
|
||||
arm_biquad_casd_df1_inst_q31 * S,
|
||||
uint8_t numStages,
|
||||
q31_t * pCoeffs,
|
||||
q31_t * pState,
|
||||
int8_t postShift)
|
||||
{
|
||||
/* Assign filter stages */
|
||||
S->numStages = numStages;
|
||||
|
||||
/* Assign postShift to be applied to the output */
|
||||
S->postShift = postShift;
|
||||
|
||||
/* Assign coefficient pointer */
|
||||
S->pCoeffs = pCoeffs;
|
||||
|
||||
/* Clear state buffer and size is always 4 * numStages */
|
||||
memset(pState, 0, (4u * (uint32_t) numStages) * sizeof(q31_t));
|
||||
|
||||
/* Assign state pointer */
|
||||
S->pState = pState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BiquadCascadeDF1 group
|
||||
*/
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user