SKY-20210407USB\Administrator 2 лет назад
Родитель
Сommit
2f6cb21fcc

+ 110 - 0
ADS1112_ATY.c

@@ -0,0 +1,110 @@
+/**
+* @file ADS1112_ATY.c
+*
+* @param Project DEVICE_GENERAL_ATY_LIB
+*
+* @author ATY
+*
+* @copyright
+*       - Copyright 2017 - 2023 MZ-ATY
+*       - This code follows:
+*           - MZ-ATY Various Contents Joint Statement -
+*               <a href="https://mengze.top/MZ-ATY_VCJS">
+*                        https://mengze.top/MZ-ATY_VCJS</a>
+*           - CC 4.0 BY-NC-SA -
+*               <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
+*                        https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
+*       - Your use will be deemed to have accepted the terms of this statement.
+*
+* @brief Familiar functions of ADS1112 for all embedded device
+*
+* @version
+*       - 1_01_230828 > ATY
+*           -# Preliminary version, first Release
+*       - Undone
+********************************************************************************
+*/
+
+#ifndef __ADS1112_ATY_C
+#define __ADS1112_ATY_C
+
+#include "ADS1112_ATY.h"
+
+/******************************* For user *************************************/
+
+/******************************************************************************/
+
+/**
+ * @brief   Set ADS1112 paramas
+ * @param   channelP channel type, default 0 -> C0-C1
+ * @param   conversion conversion, default 0
+ * @param   resolution resolution, higher resolution with lower data rate, default 3
+ * @param   gain gain, default 0
+ */
+uint8_t ADS1112_Setting(uint8_t channel, uint8_t conversion, uint8_t resolution, uint8_t gain)
+{
+    /* INP controls which two of the four analog inputs are used to measure data in the ADC.
+        INP1   INP0   V IN+   V IN-
+        0      0      AIN0    AIN1
+        0      1      AIN2    AIN3
+        1      0      AIN0    AIN3
+        1      1      AIN1    AIN3
+    */
+
+    /* Bits DR1 and DR2 control the ADS1112 data rate and resolution
+        DR1   DR0   DATA RATE   RESOLUTION
+        0     0     240SPS      12 Bits
+        0     1     60SPS       14 Bits
+        1     0     30SPS       15 Bits
+        1     1     15SPS       16 Bits
+
+    */
+
+    /* Bits PGA1 and PGA0 control the ADS1112 ADS1112 gain setting
+        PGA1    PGA0    GAIN
+        0       0       1
+        0       1       2
+        1       0       4
+        1       1       8
+    */
+    uint8_t tempReg = (1 << 7 |
+        channel << 5 |
+        conversion << 4 |
+        resolution << 2 |
+        gain);
+    return I2C_Write(ADS1112_ADDRESS, &tempReg, 1);
+}
+// ADS1112_Setting(CHANNEL_0_3, CONVERSION_CONTINUOUS, RESOLUTION_16BIT, GAIN_1);
+
+/**
+ * @brief   read data from ADS1112
+ * @param   chipAddr chip address
+ * @return  uint16_t data value
+ */
+uint16_t ADS1112_Read(uint8_t chipAddr)
+{
+    uint8_t errCount = 11;
+    uint8_t tempRealValue[3] = {0};
+    I2C_Read(chipAddr, tempRealValue, 3);
+    while(errCount--){
+        if((tempRealValue[2] & (uint8_t)0x80) != 0)
+            I2C_Read(chipAddr, tempRealValue, 3);
+    }
+    if(errCount <= 1)
+        return 0;
+    return (uint16_t)((uint16_t)((uint16_t)tempRealValue[0] << 8) | (uint16_t)tempRealValue[1]);
+}
+// ADS1112_Read(ADS1112_ADDRESS);
+
+float ADS1112_Voltage(uint16_t u16Data)
+{
+    if(u16Data > 0x7FFF)
+        return ((((float)(u16Data - 0x8000) / 65536.0f) * 2.048f * 2) + (VREF_COM - 2.048f));
+    else
+        return ((((float)(u16Data + 0x8000) / 65536.0f) * 2.048f * 2) + (VREF_COM - 2.048f));
+}
+// ADS1112_Voltage(ADS1112_Read(ADS1112_ADDRESS));
+
+#endif /* __ADS1112_ATY_C */
+
+/******************************** End Of File *********************************/

+ 81 - 0
ADS1112_ATY.h

@@ -0,0 +1,81 @@
+/**
+* @file ADS1112_ATY.h
+*
+* @param Project DEVICE_GENERAL_ATY_LIB
+*
+* @author ATY
+*
+* @copyright
+*       - Copyright 2017 - 2023 MZ-ATY
+*       - This code follows:
+*           - MZ-ATY Various Contents Joint Statement -
+*               <a href="https://mengze.top/MZ-ATY_VCJS">
+*                        https://mengze.top/MZ-ATY_VCJS</a>
+*           - CC 4.0 BY-NC-SA -
+*               <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
+*                        https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
+*       - Your use will be deemed to have accepted the terms of this statement.
+*
+* @brief Familiar functions of DS18B20 for all embedded device
+*
+* @version
+*       - 1_01_230828 > ATY
+*           -# Preliminary version, first Release
+********************************************************************************
+*/
+
+#ifndef __ADS1112_ATY_H
+#define __ADS1112_ATY_H
+
+#include "INCLUDE_ATY.h"
+#include "HW_I2C_ATY.h"
+
+/******************************* For user *************************************/
+// Set AD0/AD1 voltage level for device address, 0 for low, 1 for high, 2 for float
+#define ADS1112_AD0 0
+#define ADS1112_AD1 0
+#define VREF_COM    1.24f
+// #define __DEBUG_ADS1112_ATY
+
+/******************************************************************************/
+
+#if ((ADS1112_AD0 == 0) && (ADS1112_AD1 == 0))
+#define ADS1112_ADDRESS  (0x48)
+#elif ((ADS1112_AD0 == 0) && (ADS1112_AD1 == 2))
+#define ADS1112_ADDRESS  (0x49)
+#elif ((ADS1112_AD0 == 0) && (ADS1112_AD1 == 1))
+#define ADS1112_ADDRESS  (0x4A)
+#elif ((ADS1112_AD0 == 2) && (ADS1112_AD1 == 0))
+#define ADS1112_ADDRESS  (0x4B)
+#elif ((ADS1112_AD0 == 1) && (ADS1112_AD1 == 0))
+#define ADS1112_ADDRESS  (0x4C)
+#elif ((ADS1112_AD0 == 1) && (ADS1112_AD1 == 2))
+#define ADS1112_ADDRESS  (0x4D)
+#elif ((ADS1112_AD0 == 1) && (ADS1112_AD1 == 1))
+#define ADS1112_ADDRESS  (0x4E)
+#elif ((ADS1112_AD0 == 2) && (ADS1112_AD1 == 1))
+#define ADS1112_ADDRESS  (0x4F)
+#endif
+
+#define CHANNEL_0_1 0
+#define CHANNEL_2_3 1
+#define CHANNEL_0_3 2
+#define CHANNEL_1_3 3
+#define CONVERSION_CONTINUOUS 0
+#define CONVERSION_ONCE 1
+#define RESOLUTION_12BIT 0
+#define RESOLUTION_14BIT 1
+#define RESOLUTION_15BIT 2
+#define RESOLUTION_16BIT 3
+#define GAIN_1 0
+#define GAIN_2 1
+#define GAIN_4 2
+#define GAIN_8 3
+
+uint8_t ADS1112_Setting(uint8_t channel, uint8_t conversion, uint8_t resolution, uint8_t gain);
+uint16_t ADS1112_Read(uint8_t chipAddr);
+float ADS1112_Voltage(uint16_t u16Data);
+
+#endif /* __ADS1112_ATY_H */
+
+/******************************** End Of File *********************************/

+ 9 - 7
GP22_ATY.c

@@ -248,6 +248,7 @@ uint8_t GP22_CalcHSC(void)
     uint8_t errCount = 5;
     uint32_t hscReadValue;
     float correctionFactor;
+    mbP_GVWP = 0;
 
     while(errCount != 0)
     {
@@ -255,7 +256,7 @@ uint8_t GP22_CalcHSC(void)
         GP22_WriteData(GP22_OPCODE_INIT);
         // EN_START need to set high
         GP22_WriteData(GP22_OPCODE_CALC_HSC);
-        if(GP22_WaitInt(GP22_STEP_START_TEMP) != 0) continue;
+        if(GP22_WaitInt(GP22_STEP_START_TEMP) != 0) return GP22_STEP_CALC_HSC;
 
         hscReadValue = GP22_ReadReg(GP22_OPCODE_READ_REG | 0x00);
         // CLKHS periods * 1000 / 32.768 us
@@ -311,7 +312,7 @@ uint8_t GP22_StartTemp(void)
         //     (GP22_TEMP_REF_RES * tempRealRes[1]) / (GP22_TEMP_REF_RES - tempRealRes[1]);
         // tempRealValue[1] = ALGO_ResToKelvinTemp(tempRealRes[1], 10, 3937);
         tempRealRes[0] = (float)temp_uint32[0] / GP22_CALC_CLKHS_FREQ / tempRefResFactor;
-        tempRealValue[0] = ALGO_ResToKelvinTemp(tempRealRes[0], 10, 4100);
+        tempRealValue[0] = ALGO_ResToKelvinTemp(tempRealRes[0], 10, 3950);
         tempRealRes[1] = (float)temp_uint32[1] / GP22_CALC_CLKHS_FREQ / tempRefResFactor;
         tempRealValue[1] = ALGO_ResToKelvinTemp(tempRealRes[1], 10, 3950);
 #ifdef __DEBUG_GP22_ATY
@@ -354,6 +355,7 @@ volatile uint8_t pulseNum = 4;
 volatile uint8_t firstWaveEnable = 1;
 volatile uint16_t ignoreTime = 1200;
 volatile uint16_t offsetValue = 0;
+volatile uint8_t startPulseNum = 6;
 
 
 // #define GP22_MEASURE_US_ANALOG
@@ -404,12 +406,12 @@ void GP22_RegInit_UsWave1MHz(void)
         | GP22_CFG3FW_EN_FIRST_WAVE * firstWaveEnable
         | GP22_CFG3FW_SEL_TIMO_MB2_0 * 1
         // | GP22_CFG3FW_SEL_TIMO_MB2_0 * 0
-        | GP22_CFG3FW_DELREL3_0 * 5
-        | GP22_CFG3FW_DELREL2_0 * 4
-        | GP22_CFG3FW_DELREL1_0 * 3
+        | GP22_CFG3FW_DELREL3_0 * (startPulseNum + 2)
+        | GP22_CFG3FW_DELREL2_0 * (startPulseNum + 1)
+        | GP22_CFG3FW_DELREL1_0 * startPulseNum
         | GP22_Ids[3];
     GP22_REG[4] = GP22_CFG_KEEP_DEFAULT4
-        | GP22_CFG4FW_DIS_PW * 1            // 1: disable
+        | GP22_CFG4FW_DIS_PW * 0            // 1: disable PW
         | GP22_CFG4FW_OFFSRNG1 * (((uint16_t)offsetValue % 10) & 0x01)
         | GP22_CFG4FW_OFFSRNG2 * (((uint16_t)offsetValue % 10) & 0x02)
         | GP22_CFG4FW_EDGE_FW * (((uint16_t)offsetValue % 10) & 0x04)
@@ -473,7 +475,7 @@ uint8_t GP22_StartTof_UsWave1MHz(void)
         (float)((tofValue[2] - tofValue[1]) + (tofValue[1] - tofValue[0])) / 2
         / GP22_CALC_CLKHS_FREQ / 65536;     // ns
     waveFreq = 1 / wavePeriod;              // MHz
-    echoTimeDetect[0] = ((float)tofValue[0] / GP22_CALC_CLKHS_FREQ / 65536);
+    echoTimeDetect[0] = ((float)tofValue[1] / GP22_CALC_CLKHS_FREQ / 65536);
         // - (wavePeriod * 2);
     // if(echoTimeDetect[0] <= 0)
     //     echoTimeDetect[0] = machineDelayTime + 1;

+ 2 - 0
GP22_ATY.h

@@ -60,6 +60,7 @@ extern volatile uint8_t firstWaveEnable;
 extern volatile uint8_t pulseNum;
 extern volatile uint16_t ignoreTime;
 extern volatile uint16_t offsetValue;
+extern volatile uint8_t startPulseNum;
 /******************************************************************************/
 
 
@@ -80,6 +81,7 @@ extern float GP22_CALC_CLKHS_FREQ;
 #define GP22_TEMP_REF_RES               10.0        // KOhm
 /******************************************************************************/
 
+uint8_t GP22_Process_UsWave1MHz(uint8_t cmdCode);
 uint8_t GP22_Process_Run(uint8_t cmdCode);
 
 #define GP22_STEP_RESET                 0x01

+ 3 - 2
HW_ADC_ATY.c

@@ -90,9 +90,10 @@ uint16_t ADC_Get(uint8_t channel)
     return 0x01;
 }
 #elif defined(__STM32_HAL_ATY)
-uint16_t ADC_Get(uint8_t channel)
+#include "adc.h"
+uint16_t ADC_Get(ADC_HandleTypeDef* channel)
 {
-    uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef * hadc);
+    return HAL_ADC_GetValue(channel);
 }
 #endif /* PLATFORM */
 

+ 4 - 1
HW_ADC_ATY.h

@@ -35,8 +35,11 @@
 
 void ADC_Init(void);
 float ADC_GetVref(void);
+#if defined(__STC51_ATY)
 uint16_t ADC_Get(uint8_t channel);
-
+#elif defined(__STM32_HAL_ATY)
+uint16_t ADC_Get(ADC_HandleTypeDef* channel);
+#endif /* PLATFORM */
 
 
 #endif /* __HW_ADC_ATY_H */

+ 23 - 34
HW_GPIO_ATY.h

@@ -35,6 +35,7 @@
 #define GPIO_SET_L(Port, Pin)       Pin = 0
 #define GPIO_GET_H(Port, Pin)       Pin == 1
 #define GPIO_GET_L(Port, Pin)       Pin == 0
+#define GPIO_GET(Port, Pin)         Pin
 #define GPIO_SET_IN(Port, Pin)      Pin = 1;__NOP_ATY;__NOP_ATY
 #define GPIO_SET_OUT(Port, Pin)     Pin = 0
 
@@ -131,19 +132,6 @@ do{ \
 #define GP22_MOSI_PIN               P13
 // #endif /* __GP22_ATY_H */
 
-#ifdef __MOTOR_STEP_ATY_H
-#define MOTOR_EN_PORT               0
-#ifndef MOTOR_EN_PIN
-#define MOTOR_EN_PIN                P24
-#endif
-#define MOTOR_DIR_PORT              0
-#define MOTOR_DIR_PIN               P22
-#define MOTOR_STEP_PORT             0
-#define MOTOR_STEP_PIN              P23
-#define MOTOR_DIAG_PORT             0
-#define MOTOR_DIAG_PIN              P55
-#endif /* __MOTOR_STEP_ATY_H */
-
 #ifdef __MOTOR_DC_ATY_H
 #define MOTOR_A_PORT                0
 #ifndef MOTOR_A_PIN
@@ -168,11 +156,22 @@ do{ \
 #elif defined(__STM32_HAL_ATY)
 #ifdef __LED_ATY_H
 #if !defined(SYSLED_PORT) && !defined(SYSLED_PIN)
-#define SYSLED_PORT                 SYSLED_O_GPIO_Port
-#define SYSLED_PIN                  SYSLED_O_Pin
+#define SYSLED_PORT                 SYSLED_GPIO_Port
+#define SYSLED_PIN                  SYSLED_Pin
 #endif /* SYSLED_PORT SYSLED_PIN */
 #endif /* __LED_ATY_H */
 
+#ifdef __MOTOR_STEP_ATY_H
+#define MOTOR_EN_PORT               MO2_EN_GPIO_Port
+#define MOTOR_EN_PIN                MO2_EN_Pin
+#define MOTOR_DIR_PORT              MO2_DIR_GPIO_Port
+#define MOTOR_DIR_PIN               MO2_DIR_Pin
+#define MOTOR_STEP_PORT             MO2_STEP_GPIO_Port
+#define MOTOR_STEP_PIN              MO2_STEP_Pin
+#define MOTOR_DIAG_PORT             0
+#define MOTOR_DIAG_PIN              0
+#endif /* __MOTOR_STEP_ATY_H */
+
 #ifndef __I2C_HARDWARE_ATY
 #define I2C_SCL_PORT                I2C_SCL_GPIO_Port
 #define I2C_SCL_PIN                 I2C_SCL_Pin
@@ -181,27 +180,17 @@ do{ \
 #endif /* __I2C_HARDWARE_ATY */
 
 #ifdef __GP22_ATY_H
-#define GP22_SIGNAL_PORT            SPI1_SIGNAL_GPIO_Port
-#define GP22_SIGNAL_PIN             SPI1_SIGNAL_Pin
-
-#define GP22_CSN_PORT               SPI1_CSN_GPIO_Port
-#define GP22_CSN_PIN                SPI1_CSN_Pin
-#define GP22_RST_PORT               SPI1_RST_GPIO_Port
-#define GP22_RST_PIN                SPI1_RST_Pin
-#define GP22_INT_PORT               SPI1_INT_GPIO_Port
-#define GP22_INT_PIN                SPI1_INT_Pin
+#define GP22_SIGNAL_PORT            0
+#define GP22_SIGNAL_PIN             0
+
+#define GP22_CSN_PORT               TDC_CSN_GPIO_Port
+#define GP22_CSN_PIN                TDC_CSN_Pin
+#define GP22_RST_PORT               TDC_RST_GPIO_Port
+#define GP22_RST_PIN                TDC_RST_Pin
+#define GP22_INT_PORT               TDC_INT_GPIO_Port
+#define GP22_INT_PIN                TDC_INT_Pin
 #endif /* __GP22_ATY_H */
 
-#ifdef __MOTOR_STEP_ATY_H
-#define MOTOR_EN_PORT               MOTOR_EN_GPIO_Port
-#define MOTOR_EN_PIN                MOTOR_EN_Pin
-#define MOTOR_DIR_PORT              MOTOR_DIR_GPIO_Port
-#define MOTOR_DIR_PIN               MOTOR_DIR_Pin
-#define MOTOR_STEP_PORT             MOTOR_STEP_GPIO_Port
-#define MOTOR_STEP_PIN              MOTOR_STEP_Pin
-#define MOTOR_DIAG_PORT             MOTOR_DIAG_GPIO_Port
-#define MOTOR_DIAG_PIN              MOTOR_DIAG_Pin
-#endif /* __MOTOR_STEP_ATY_H */
 #endif /* PLATFORM */
 
 

+ 2 - 2
HW_I2C_ATY.c

@@ -188,8 +188,8 @@ void I2C_WriteByte(uint8_t byte)
     I2C_SDA_SET_H;
     OLED_Delay(SHORT_DELAY);
     I2C_SCL_SET_H;
-    OLED_Delay(SHORT_DELAY);
-    I2C_SCL_SET_L;
+    // OLED_Delay(SHORT_DELAY);
+    // I2C_SCL_SET_L;
 }
 
 /**

+ 43 - 17
HW_PWM_ATY.c

@@ -77,6 +77,20 @@ void PWM_Start(uint32_t periodS, uint8_t dutyS, uint8_t channelS)
     CR = 1;             // start PCA
 }
 
+/**
+ * @brief   stop PWM output with specified level
+ * @param   level IO level after stop PWM
+ * @param   channelS channel to start or to change param
+ * @note    Undone, not real stop
+ */
+void PWM_Stop(uint8_t level, uint8_t channelS)
+{
+    if(level)
+        PWM_Start(1000, level * 1000, channelS);
+    else
+        PWM_Start(1000, 0, channelS);
+}
+
 /**
  * @brief   stop PWM output with specified level with PCA
  * @param   level IO level after stop PWM
@@ -180,7 +194,7 @@ void PWM_Start(uint32_t periodS, float dutyS, uint8_t channelS)
         PWMB_CCR6 = dutyS / 100.0 * periodS;                    // Set dutys time
     }
     else if(channelS == PWM_CHANNEL_7P){
-        PWMB_PS = (PWMB_PS & 0xCF) | (PWM_PIN_POS_2 << 4);      //
+        PWMB_PS = (PWMB_PS & 0xCF) | (PWM_PIN_POS_0 << 4);      //
         PWMB_CCER2 &= 0xF0;
         PWMB_CCMR3 = 0x60;
         PWMB_CCER2 |= 0x01;
@@ -229,36 +243,48 @@ void PWM_Stop(uint8_t level, uint8_t channelS)
  * @param   channelS channel to start or to change param
  * @note    Undone
  */
-void PWM_Start(uint32_t periodS, uint8_t dutyS, uint8_t channelS)
+void PWM_Start(uint32_t periodS, float dutyS, uint8_t channelS)
 {
-    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_4);
-    TIM1->CNT = 0;
-    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4);
-    TIM1->ARR = periodS;
-    TIM1->CCR4 = dutyS;
-    TIM1->EGR = TIM_EGR_UG;
+    if(channelS == PWM_T2C2)
+        HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_2);
+    else if(channelS == PWM_T3C3)
+        HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_3);
+    // TIM2->CNT = 0;
+    // TIM2->ARR = periodS;
+    // TIM2->CCR2 = (uint32_t)(periodS * dutyS);
+    // TIM2->EGR = TIM_EGR_UG;
+    if(channelS == PWM_T2C2)
+        HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
+    else if(channelS == PWM_T3C3)
+        HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
+    __HAL_TIM_SET_AUTORELOAD(&htim2, periodS);
+    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, (uint32_t)(periodS / 100 * dutyS));
 }
 
 /**
  * @brief   stop PWM output with specified level
  * @param   level IO level after stop PWM
- * @note    Undone
+ * @param   channelS channel to start or to change param
+ * @note    Undone, not real stop
  */
-void PWM_Stop(uint8_t level)
+void PWM_Stop(uint8_t level, uint8_t channelS)
 {
     if(level)
     {
-        TIM1->ARR = 0;
-        TIM1->CCR4 = 0;
-        TIM1->EGR = TIM_EGR_UG;
+        TIM2->ARR = 0;
+        TIM2->CCR4 = 0;
+        TIM2->EGR = TIM_EGR_UG;
     }
     else
     {
-        TIM1->ARR = 0;
-        TIM1->CCR4 = 1;
-        TIM1->EGR = TIM_EGR_UG;
+        TIM2->ARR = 0;
+        TIM2->CCR4 = 1;
+        TIM2->EGR = TIM_EGR_UG;
     }
-    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_4);
+    if(channelS == PWM_T2C2)
+        HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
+    else if(channelS == PWM_T3C3)
+        HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
 }
 
 #elif defined(__ESP8266_RTOS_ATY)

+ 7 - 0
HW_PWM_ATY.h

@@ -32,6 +32,7 @@
 
 /******************************* For user *************************************/
 // #define __DEBUG_HW_PWM_ATY
+#if defined(__STC51_ATY)
 #define PWM1_CHOSE PWM_PIN_POS_0
 #define PWM2_CHOSE PWM_PIN_POS_0
 #define PWM3_CHOSE PWM_PIN_POS_0
@@ -40,6 +41,8 @@
 #define PWM6_CHOSE PWM_PIN_POS_0
 #define PWM7_CHOSE PWM_PIN_POS_0
 #define PWM8_CHOSE PWM_PIN_POS_0
+#elif defined(__STM32_HAL_ATY)
+#endif /* PLATFORM */
 
 /******************************************************************************/
 
@@ -63,6 +66,10 @@
 #define PWM_PIN_POS_3 0x03      // PWMN_4
 
 #elif defined(__STM32_HAL_ATY)
+#define PWM_T2C2 0x22
+#define PWM_T3C3 0x33
+// #define PWM_T
+// #define PWM_C
 #elif defined(__ESP8266_RTOS_ATY)
 #endif /* PLATFORM */
 

+ 2 - 2
HW_RESET_ATY.c

@@ -43,8 +43,8 @@ __WEAK_ATY void SoftReset(void)
 #elif defined(__HC32_ATY) || \
     defined(__STM32_SPL_ATY) || \
     defined(__STM32_HAL_ATY)|| \
-    defined(__STM32_LL_ATY)
-    // defined(__ICCARM__) || \
+    defined(__STM32_LL_ATY) 
+    // defined(__ICCARM__) ||
     // defined(__CC_ARM)
     // for all CMSIS devices
     __set_FAULTMASK(1);     // close all IT

+ 52 - 14
HW_UART_ATY.c

@@ -102,8 +102,13 @@ void UartSendByte(uint8_t byte)
 }
 
 #elif defined(__STM32_HAL_ATY)
+#include "usart.h"
 void UartSendByte(uint8_t byte)
 {
+    uint8_t i = 0;
+    for(i = 0; i < uartMsgStruct_t.rxCount; i++)
+        uartMsgStruct_t.rx[i] = 0;
+    uartMsgStruct_t.rxCount = 0;
 #ifdef LL
     LL_USART_TransmitData8(PRINTF_UART, byte);
     while(!LL_USART_IsActiveFlag_TC(PRINTF_UART)){}
@@ -112,6 +117,39 @@ void UartSendByte(uint8_t byte)
 #endif
 }
 
+/**
+ * @brief   uart hardware init
+ * @note    put at main init
+ *          use DMA IDEL type, open uart IT and add rx dma, mode in Normal(not Circular!), data with byte
+ */
+void UartInit(void)
+{
+    // __HAL_UART_ENABLE_IT(&PRINTF_UART, UART_IT_IDLE);
+    HAL_UARTEx_ReceiveToIdle_DMA(&PRINTF_UART, uartMsgStruct_t.rx, UART_RX_MAX_LEN);
+    __HAL_DMA_DISABLE_IT(&PRINTF_DMA, DMA_IT_HT);
+
+    uartMsgStruct_t.rxCount = 0x00;
+    uartMsgStruct_t.txCount = 0x00;
+    uartMsgStruct_t.busyFlag = 0;
+}
+
+
+void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef* huart, uint16_t Size)
+{
+    if(huart->Instance == USART1){
+        HAL_UART_DMAStop(&PRINTF_UART);
+        uartMsgStruct_t.overCount = 0;
+        uartMsgStruct_t.rxCount = UART_RX_MAX_LEN - __HAL_DMA_GET_COUNTER(&PRINTF_DMA);
+
+        HAL_UARTEx_ReceiveToIdle_DMA(&PRINTF_UART, uartMsgStruct_t.rx, UART_RX_MAX_LEN);
+        __HAL_DMA_DISABLE_IT(&PRINTF_DMA, DMA_IT_HT);
+    }
+
+    /* if process is not too long, process function can be used at this call back;
+        otherwise put process at other cycle like while or timer cycle */
+    // PrintfReceiveProcess();
+}
+
 
 
 
@@ -151,8 +189,8 @@ FILE __stdout;
 PUTCHAR_PROTOTYPE \
 {
 #ifdef LL
-    LL_USART_TransmitData8(USART1, ch);
-    while(!LL_USART_IsActiveFlag_TC(USART1)){}
+    LL_USART_TransmitData8(PRINTF_UART, ch);
+    while(!LL_USART_IsActiveFlag_TC(PRINTF_UART)){}
 #else
     HAL_UART_Transmit(&PRINTF_UART, (uint8_t*)&ch, 1, 0xFFFF);
 #endif
@@ -168,7 +206,7 @@ GETCHAR_PROTOTYPE \
 
 #ifdef DEBUG_PRINTF_RECEIVE
 uint8_t uartPrintfRxBuf[PRINTF_RX_MAX_LEN];
-struct _uartMsgStruct uartPrintfMsgStruct = {uartPrintfRxBuf};
+struct _uartMsgStruct uartPrintfMsgStruct = {*uartPrintfRxBuf,0};
 
 /**
  * @brief   init uart IT and DMA etc.
@@ -200,17 +238,17 @@ __WEAK_ATY void PrintfReceiveProcess(void)
 
 __WEAK_ATY void PrintfReceiveProcess_User(struct _uartMsgStruct* ptr)
 {
-    if(memcmp("DSTART", (char*)ptr->rx, strlen("DSTART")) == 0)
-    {
-        printf("\r\nDebug START!");
-    }
-    else if(memcmp("temp", (char*)ptr->rx, strlen("temp")) == 0)
-    {
-        printf("\r\ntemp %c%c%c",
-            ptr->rx[strlen("temp_")],
-            ptr->rx[strlen("temp_") + 1],
-            ptr->rx[strlen("temp_") + 2]);
-    }
+    // if(memcmp("DSTART", (char*)ptr->rx, strlen("DSTART")) == 0)
+    // {
+    //     printf("\r\nDebug START!");
+    // }
+    // else if(memcmp("temp", (char*)ptr->rx, strlen("temp")) == 0)
+    // {
+    //     printf("\r\ntemp %c%c%c",
+    //         ptr->rx[strlen("temp_")],
+    //         ptr->rx[strlen("temp_") + 1],
+    //         ptr->rx[strlen("temp_") + 2]);
+    // }
 }
 
 void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef* huart, uint16_t Size)

+ 5 - 0
HW_UART_ATY.h

@@ -29,11 +29,16 @@
 
 #include "INCLUDE_ATY.h"
 
+#include "stdio.h"
+// #include "stdlib.h"
+// #include "string.h"
+
 /******************************* For user *************************************/
 
 /******************************************************************************/
 
 #define UART_RX_MAX_LEN (9 + (15 * 4))
+#define PRINTF_RX_MAX_LEN 64
 // #define UART_RX_MAX_LEN 16
 typedef struct _uartMsgStruct{
     uint8_t rx[UART_RX_MAX_LEN];

+ 11 - 10
INCLUDE_ATY.h

@@ -137,7 +137,7 @@ typedef unsigned long uint32_t;
 #if defined(SDCC) || defined(__SDCC) || defined(__CX51__) || defined(__C51__)
 typedef unsigned long int uint64_t;  // uint64_t at 64 bit platform with ulong
 #else
-typedef unsigned long long int int64_t;
+typedef unsigned long long int uint64_t;
 #endif /* uint64_t */
 #endif /* _UINT64_T */
 
@@ -256,8 +256,9 @@ extern void _nop_(void);
 // #pragma diag_suppress 223
 #endif
 
-
-
+#ifdef __STC51_ATY
+#define BIG_ENDIAN                                      // chip in big endian mode, like 51
+#endif
 
 #if defined(__STC51_ATY)
 #define LOG_ATY(__STRING) UartSendStr(__STRING)
@@ -265,18 +266,19 @@ extern void _nop_(void);
     defined(__STM32_SPL_ATY) || \
     defined(__STM32_HAL_ATY) || \
     defined(__STM32_LL_ATY)
-#include "STM32_HAL_PRINTF_ATY.h"
+#include "HW_UART_ATY.h"
 #include "stdarg.h"
-#define LOG_ATY(__STRING, ...) printf(__STRING,##__VA_ARGS__)   // C99
+#define LOG_ATY(__STRING) printf(__STRING)   // C99
+#define LOG_ATY__(__STRING, ...) printf(__STRING,##__VA_ARGS__)   // C99
 #else
 #define LOG_ATY(__STRING)
 #endif
 
 
-#if !defined(__PRINTF_ATY) && !defined(__stdio_h) && !defined(__STM32_HAL_ATY)
-#include "stdarg.h"
-__WEAK_ATY void printf(uint8_t*, ...);
-#endif /* __PRINTF_ATY */
+// #if !defined(__PRINTF_ATY) && !defined(__stdio_h) && !defined(__STM32_HAL_ATY)
+// #include "stdarg.h"
+// __WEAK_ATY void printf(uint8_t*, ...);
+// #endif /* __PRINTF_ATY */
 
 /*
 // todo, not tested and need to be adjust
@@ -324,7 +326,6 @@ __WEAK_ATY void printf(uint8_t*, ...);
 // #define PWMH_N TIM1
 // #define PWMH_N 1
 
-
 // #define DEBUG_PRINTF_RECEIVE
 // #define PRINTF_UART huart3
 // #define PRINTF_DMA hdma_usart3_rx

+ 5 - 0
ISP.ASM

@@ -0,0 +1,5 @@
+CSEG AT 0133H
+JMP P1INT_ISR
+P1INT_ISR:
+JMP 006BH
+END

+ 1 - 1
LED_ATY.c

@@ -36,7 +36,7 @@
 /******************************************************************************/
 
 uint32_t ledBlinkStep = 0;
-uint8_t ledBlinkType = 0;
+uint8_t ledBlinkType = 20;
 /**
  * @brief   set sysled blink ledBlinkType
  * @note    put this function at timer IT callback, change

+ 52 - 24
MODBUS_LOW_ATY.c

@@ -141,7 +141,7 @@ union{ float f_t; uint8_t u8_t[4]; }mbFloatChange_u;
 void Modbus_Process(uint8_t* buf, uint8_t len)
 {
     uint8_t sendBuf[(MODBUS_REG_HOLDING_SIZE * 4) + 4] = {0x00};
-    uint16_t snedBufSize = 4;
+    uint16_t sendBufSize = 4;
     if(len < 4) return;                         // check buf min size
     if(buf[0] != MODBUS_ADDR) return;           // check addr
     if(CheckCrc16Modbus(buf, len)) return;      // check crc
@@ -158,18 +158,25 @@ void Modbus_Process(uint8_t* buf, uint8_t len)
             if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){
                 sendBuf[1] = buf[1] + 0x80;
                 sendBuf[2] = 0x02;
-                snedBufSize = 6;
+                sendBufSize = 6;
                 break;
             }
             sendBuf[2] = regCount * 4;
-            snedBufSize += 1;
+            sendBufSize += 1;
             for(i = 0; i < regCount; i++){
                 mbFloatChange_u.f_t = mbRegHoding[startAddr + i];
+#ifdef BIG_ENDIAN
                 sendBuf[2 + (i * 4) + 1] = mbFloatChange_u.u8_t[0];
                 sendBuf[2 + (i * 4) + 2] = mbFloatChange_u.u8_t[1];
                 sendBuf[2 + (i * 4) + 3] = mbFloatChange_u.u8_t[2];
                 sendBuf[2 + (i * 4) + 4] = mbFloatChange_u.u8_t[3];
-                snedBufSize += 4;
+#else
+                sendBuf[2 + (i * 4) + 1] = mbFloatChange_u.u8_t[3];
+                sendBuf[2 + (i * 4) + 2] = mbFloatChange_u.u8_t[2];
+                sendBuf[2 + (i * 4) + 3] = mbFloatChange_u.u8_t[1];
+                sendBuf[2 + (i * 4) + 4] = mbFloatChange_u.u8_t[0];
+#endif
+                sendBufSize += 4;
             }
             break; }
         // case MODBUS_FUNC_READ_INPUT_REGISTERS:{break; }
@@ -181,22 +188,36 @@ void Modbus_Process(uint8_t* buf, uint8_t len)
             if(startAddr >= MODBUS_REG_HOLDING_SIZE){
                 sendBuf[1] = buf[1] + 0x80;
                 sendBuf[2] = 0x02;
-                snedBufSize = 6;
+                sendBufSize = 6;
                 break;
             }
+#ifdef BIG_ENDIAN
             mbFloatChange_u.u8_t[0] = buf[4];
             mbFloatChange_u.u8_t[1] = buf[5];
             mbFloatChange_u.u8_t[2] = buf[6];
             mbFloatChange_u.u8_t[3] = buf[7];
+#else
+            mbFloatChange_u.u8_t[3] = buf[4];
+            mbFloatChange_u.u8_t[2] = buf[5];
+            mbFloatChange_u.u8_t[1] = buf[6];
+            mbFloatChange_u.u8_t[0] = buf[7];
+#endif
             regValue = mbFloatChange_u.f_t;
             mbRegHoding[startAddr] = regValue;
             sendBuf[2] = startAddr >> 8;
             sendBuf[3] = startAddr;
+#ifdef BIG_ENDIAN
             sendBuf[4] = mbFloatChange_u.u8_t[0];
             sendBuf[5] = mbFloatChange_u.u8_t[1];
             sendBuf[6] = mbFloatChange_u.u8_t[2];
             sendBuf[7] = mbFloatChange_u.u8_t[3];
-            snedBufSize += 6;
+#else
+            sendBuf[4] = mbFloatChange_u.u8_t[3];
+            sendBuf[5] = mbFloatChange_u.u8_t[2];
+            sendBuf[6] = mbFloatChange_u.u8_t[1];
+            sendBuf[7] = mbFloatChange_u.u8_t[0];
+#endif
+            sendBufSize += 6;
             break; }
         case MODBUS_FUNC_WRITE_MULTY_HOLDING_REGISTERS:{
             uint16_t i = 0, startAddr = 0, regCount = 0;
@@ -205,16 +226,23 @@ void Modbus_Process(uint8_t* buf, uint8_t len)
             if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){
                 sendBuf[1] = buf[1] + 0x80;
                 sendBuf[2] = 0x02;
-                snedBufSize = 6;
+                sendBufSize = 6;
                 break;
             }
             for(i = 0; i < regCount; i++)
             {
                 float regValue = 0.0;
+#ifdef BIG_ENDIAN
                 mbFloatChange_u.u8_t[0] = buf[6 + (i * 4) + 1];
                 mbFloatChange_u.u8_t[1] = buf[6 + (i * 4) + 2];
                 mbFloatChange_u.u8_t[2] = buf[6 + (i * 4) + 3];
                 mbFloatChange_u.u8_t[3] = buf[6 + (i * 4) + 4];
+#else
+                mbFloatChange_u.u8_t[3] = buf[6 + (i * 4) + 1];
+                mbFloatChange_u.u8_t[2] = buf[6 + (i * 4) + 2];
+                mbFloatChange_u.u8_t[1] = buf[6 + (i * 4) + 3];
+                mbFloatChange_u.u8_t[0] = buf[6 + (i * 4) + 4];
+#endif
                 regValue = mbFloatChange_u.f_t;
                 mbRegHoding[startAddr + i] = regValue;
             }
@@ -223,17 +251,17 @@ void Modbus_Process(uint8_t* buf, uint8_t len)
             sendBuf[3] = startAddr;
             sendBuf[4] = regCount >> 8;
             sendBuf[5] = regCount;
-            snedBufSize += 4;
+            sendBufSize += 4;
             break; }
         default:{
             sendBuf[1] = buf[1] + 0x80;
             sendBuf[2] = 0x01;
-            snedBufSize = 6;
+            sendBufSize = 6;
             break; }
     }
-    sendBuf[snedBufSize - 2] = GenCrc16ModbusHL(sendBuf, snedBufSize - 2, 1);
-    sendBuf[snedBufSize - 1] = GenCrc16ModbusHL(sendBuf, snedBufSize - 2, 0);
-    UartSendBytes(sendBuf, snedBufSize);
+    sendBuf[sendBufSize - 2] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 1);
+    sendBuf[sendBufSize - 1] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 0);
+    UartSendBytes(sendBuf, sendBufSize);
 }
 
 #else
@@ -246,7 +274,7 @@ uint16_t mbRegHoding[MODBUS_REG_HOLDING_SIZE] = {0x0000};
 void Modbus_Process(uint8_t* buf, uint8_t len)
 {
     uint8_t sendBuf[(MODBUS_REG_HOLDING_SIZE * 2) + 4] = {0x00};
-    uint16_t snedBufSize = 4;
+    uint16_t sendBufSize = 4;
     if(len < 4) return;                         // check buf min size
     if(buf[0] != MODBUS_ADDR) return;           // check addr
     if(CheckCrc16Modbus(buf, len)) return;      // check crc
@@ -263,15 +291,15 @@ void Modbus_Process(uint8_t* buf, uint8_t len)
             if(startAddr + regCount - 1 >= MODBUS_REG_HOLDING_SIZE){
                 sendBuf[1] = buf[1] + 0x80;
                 sendBuf[2] = 0x02;
-                snedBufSize = 6;
+                sendBufSize = 6;
                 break;
             }
             sendBuf[2] = regCount * 2;
-            snedBufSize += 1;
+            sendBufSize += 1;
             for(i = 0; i < regCount; i++){
                 sendBuf[3 + (i * 2)] = mbRegHoding[startAddr + i] >> 8;
                 sendBuf[3 + (i * 2) + 1] = mbRegHoding[startAddr + i];
-                snedBufSize += 2;
+                sendBufSize += 2;
             }
             break; }
         // case MODBUS_FUNC_READ_INPUT_REGISTERS:{break; }
@@ -283,7 +311,7 @@ void Modbus_Process(uint8_t* buf, uint8_t len)
             if(startAddr >= MODBUS_REG_HOLDING_SIZE){
                 sendBuf[1] = buf[1] + 0x80;
                 sendBuf[2] = 0x02;
-                snedBufSize = 6;
+                sendBufSize = 6;
                 break;
             }
             mbRegHoding[startAddr] = regValue;
@@ -291,7 +319,7 @@ void Modbus_Process(uint8_t* buf, uint8_t len)
             sendBuf[3] = startAddr;
             sendBuf[4] = regValue >> 8;
             sendBuf[5] = regValue;
-            snedBufSize += 4;
+            sendBufSize += 4;
             break; }
         case MODBUS_FUNC_WRITE_MULTY_HOLDING_REGISTERS:{
             uint16_t i = 0, startAddr = 0, regCount = 0;
@@ -300,7 +328,7 @@ void Modbus_Process(uint8_t* buf, uint8_t len)
             if(startAddr + regCount - 1 >= MODBUS_REG_HOLDING_SIZE){
                 sendBuf[1] = buf[1] + 0x80;
                 sendBuf[2] = 0x02;
-                snedBufSize = 6;
+                sendBufSize = 6;
                 break;
             }
             for(i = 0; i < regCount; i++)
@@ -310,18 +338,18 @@ void Modbus_Process(uint8_t* buf, uint8_t len)
             sendBuf[3] = startAddr;
             sendBuf[4] = regCount >> 8;
             sendBuf[5] = regCount;
-            snedBufSize += 4;
+            sendBufSize += 4;
             break; }
         default:{
             sendBuf[1] = buf[1] + 0x80;
             sendBuf[2] = 0x01;
-            snedBufSize = 6;
+            sendBufSize = 6;
             break;
         }
     }
-    sendBuf[snedBufSize - 2] = GenCrc16ModbusHL(sendBuf, snedBufSize - 2, 0);
-    sendBuf[snedBufSize - 1] = GenCrc16ModbusHL(sendBuf, snedBufSize - 2, 1);
-    UartSendBytes(sendBuf, snedBufSize);
+    sendBuf[sendBufSize - 2] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 0);
+    sendBuf[sendBufSize - 1] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 1);
+    UartSendBytes(sendBuf, sendBufSize);
 }
 #endif /* MODBUS_FLOAT_MODE */
 

+ 4 - 1
MODBUS_LOW_ATY.h

@@ -36,11 +36,14 @@
 #define MODBUS_FLOAT_CODE_MODE
 
 #ifndef MODBUS_REG_HOLDING_SIZE
-#define MODBUS_REG_HOLDING_SIZE                    60   // set --model-large at 51
+#define MODBUS_REG_HOLDING_SIZE                    50   // set --model-large at 51
 #endif
 #ifndef MODBUS_ADDR
 #define MODBUS_ADDR                                0x01
 #endif
+// #ifdef __STC51_ATY                                      // move to INCLUDE.h
+// #define BIG_ENDIAN                                      // chip in big endian mode
+// #endif
 /******************************************************************************/
 
 #define MODBUS_FUNC_READ_COILS                     0x01

+ 9 - 9
MOTOR_DC_ATY.c

@@ -41,7 +41,7 @@ uint32_t motorSpeed = 0;
 uint32_t motorSoftTime = 0;
 uint32_t motorTime = 0;
 
-uint32_t motorStartCounter = 0;
+uint32_t motorSpeedCounter = 0;
 uint32_t motorStopCounter = 0;
 
 uint8_t motorSetState = 0;          // 0: stop, 1: start hold, 2: start soft, 3: run speed, 4: change dir, 5: stop state, soft set 0 after use, 10: scram motor
@@ -90,7 +90,7 @@ void MotorStop(void)
         // PWM_Stop(0, Motor_Channel);
         // MOTOR_EN_SET_DISABLE;
         MOTOR_STOP;
-        motorStartCounter = 0;
+        motorSpeedCounter = 0;
         motorStopCounter = 0;
 #ifdef __DEBUG_MOTOR_DC_ATY
         printf("\r\nMotor Stop");
@@ -113,25 +113,25 @@ void MotorStop(void)
 void MotorStateMachine_DC(void)
 {
     if(motorSetState == 4){
-        motorStartCounter = 0;
+        motorSpeedCounter = 0;
         motorStopCounter = 0;
         motorSetState = 1;
         motorDir = !motorDir;
     }
     else if(motorSetState == 3){
-        motorStartCounter = motorSoftTime;
+        motorSpeedCounter = motorSoftTime;
         motorSetState = 1;
         MotorStart(motorDir, motorSpeed);
     }
     else if(motorSetState == 2){
-        motorStartCounter = 0;
+        motorSpeedCounter = 0;
         motorSetState = 1;
         MotorStart(motorDir, motorSoftSpeed);
     }
     else if(motorSetState == 1){
-        if(motorStartCounter == motorSoftTime)
+        if(motorSpeedCounter == motorSoftTime)
             motorSetState = 3;
-        else if(motorStartCounter == (motorSoftTime + motorTime))
+        else if(motorSpeedCounter == (motorSoftTime + motorTime))
             motorSetState = 5;
     }
     else if(motorSetState == 10){
@@ -141,11 +141,11 @@ void MotorStateMachine_DC(void)
     else{ MotorStop(); }    // 5 0
 
     if(motorEn == 0){
-        motorStartCounter = 0;
+        motorSpeedCounter = 0;
         motorStopCounter++;
     }
     else{
-        motorStartCounter++;
+        motorSpeedCounter++;
         motorStopCounter = 0;
     }
 }

+ 1 - 1
MOTOR_DC_ATY.h

@@ -45,7 +45,7 @@ extern uint32_t motorSpeed;
 extern uint32_t motorSoftTime;
 extern uint32_t motorTime;
 
-extern uint32_t motorStartCounter;
+extern uint32_t motorSpeedCounter;
 extern uint32_t motorStopCounter;       // for stall detection or driver error(TMC2209)
 
 extern uint8_t motorSetState;           // 0: stop, 1: start hold, 2: start soft, 3: run speed, 4: change dir, 5: stop state, soft set 0 after use

+ 406 - 119
MOTOR_STEP_ATY.c

@@ -37,90 +37,198 @@
 
 /******************************************************************************/
 
+motorStep_t motorStep_t_Group[MOTOR_COUNT] =
+{
+#ifdef S_PARAM_C
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, S_PARAM_C},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, S_PARAM_C},
+#else
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+#endif
+};
 
-uint8_t motorEn = 0;
-uint8_t motorDir = MOTOR_DIR_OUT;
-uint32_t motorSoftSpeed = 0;
-uint32_t motorSpeed = 0;
-uint32_t motorSoftTime = 0;
-uint32_t motorTime = 0;
+/**
+ * @brief   set motor enable or disbale
+ * @param   enable 0 for disable, 1 for enable
+ * @param   channel motor channel
+ */
+void MotorSetAble(uint8_t enable, uint8_t channel)
+{
+    motorStep_t_Group[channel].motorEn = enable;
+#if (MOTOR_COUNT >= 1)
+    if(channel == 0){
+        if(enable){ GPIO_SET_L(MOTOR_EN_PORT_0, MOTOR_EN_PIN_0); }
+        else{ GPIO_SET_H(MOTOR_EN_PORT_0, MOTOR_EN_PIN_0); }
+    }
+#endif
+#if (MOTOR_COUNT >= 2)
+    if(channel == 1){
+        if(enable){ GPIO_SET_L(MOTOR_EN_PORT_1, MOTOR_EN_PIN_1); }
+        else{ GPIO_SET_H(MOTOR_EN_PORT_1, MOTOR_EN_PIN_1); }
+    }
+#endif
+#if (MOTOR_COUNT >= 3)
+    if(channel == 2){
+        if(enable){ GPIO_SET_L(MOTOR_EN_PORT_2, MOTOR_EN_PIN_2); }
+        else{ GPIO_SET_H(MOTOR_EN_PORT_2, MOTOR_EN_PIN_2); }
+    }
+#endif
+}
 
-uint32_t motorStartCounter = 0;
-uint32_t motorStopCounter = 0;      // for stall detection or driver error(TMC2209)
+/**
+ * @brief   set motor direction
+ * @param   dir 0 for MOTOR_DIR_IN, 1 for MOTOR_DIR_OUT
+ * @param   channel motor channel
+ */
+void MotorSetDirection(uint8_t dir, uint8_t channel)
+{
+    motorStep_t_Group[channel].motorDir = dir;
+#if (MOTOR_COUNT >= 1)
+    if(channel == 0){
+        if(dir){ GPIO_SET_H(MOTOR_DIR_PORT_0, MOTOR_DIR_PIN_0); }
+        else{ GPIO_SET_L(MOTOR_DIR_PORT_0, MOTOR_DIR_PIN_0); }
+    }
+#endif
+#if (MOTOR_COUNT >= 2)
+    if(channel == 1){
+        if(dir){ GPIO_SET_H(MOTOR_DIR_PORT_1, MOTOR_DIR_PIN_1); }
+        else{ GPIO_SET_L(MOTOR_DIR_PORT_1, MOTOR_DIR_PIN_1); }
+    }
+#endif
+#if (MOTOR_COUNT >= 3)
+    if(channel == 2){
+        if(dir){ GPIO_SET_H(MOTOR_DIR_PORT_2, MOTOR_DIR_PIN_2); }
+        else{ GPIO_SET_L(MOTOR_DIR_PORT_2, MOTOR_DIR_PIN_2); }
+    }
+#endif
+}
 
-uint8_t motorSetState = 0;          // 0: stop, 1: start hold, 2: start soft, 3: run speed, 4: change dir, 5: stop state, soft set 0 after use, 10: scram motor
+/**
+ * @brief   set motor step pin voltage level
+ * @param   level 0 for low, 1 for high
+ * @param   channel motor channel
+ */
+void MotorSetStepLevel(uint8_t level, uint8_t channel)
+{
+    motorStep_t_Group[channel].motorStepLevel = level;
+#if (MOTOR_COUNT >= 1)
+    if(channel == 0){
+        if(level){ GPIO_SET_H(MOTOR_STEP_PORT_0, MOTOR_STEP_PIN_0); }
+        else{ GPIO_SET_L(MOTOR_STEP_PORT_0, MOTOR_STEP_PIN_0); }
+    }
+#endif
+#if (MOTOR_COUNT >= 2)
+    if(channel == 1){
+        if(level){ GPIO_SET_H(MOTOR_STEP_PORT_1, MOTOR_STEP_PIN_1); }
+        else{ GPIO_SET_L(MOTOR_STEP_PORT_1, MOTOR_STEP_PIN_1); }
+    }
+#endif
+#if (MOTOR_COUNT >= 3)
+    if(channel == 2){
+        if(level){ GPIO_SET_H(MOTOR_STEP_PORT_2, MOTOR_STEP_PIN_2); }
+        else{ GPIO_SET_L(MOTOR_STEP_PORT_2, MOTOR_STEP_PIN_2); }
+    }
+#endif
+}
 
-float speedIncreaseStep = 0.0f;
-float S_paramA = 0.0f;
-#ifdef S_PARAM_C
-float S_paramC = S_PARAM_C;
-#else
-float S_paramC = 0.0f;
+/**
+ * @brief   get TMC2209 diag pin voltage level
+ * @param   channel motor channel
+ * @return  uint8_t 0 for low, 1 fo high
+ */
+uint8_t MotorGetDiagLevel(uint8_t channel)
+{
+#if (MOTOR_COUNT >= 1)
+    if(channel == 0){ motorStep_t_Group[channel].motorDiag = GPIO_GET(MOTOR_DIAG_PORT_0, MOTOR_DIAG_PIN_0); }
 #endif
+#if (MOTOR_COUNT >= 2)
+    if(channel == 1){ motorStep_t_Group[channel].motorDiag = GPIO_GET(MOTOR_DIAG_PORT_1, MOTOR_DIAG_PIN_1); }
+#endif
+#if (MOTOR_COUNT >= 3)
+    if(channel == 2){ motorStep_t_Group[channel].motorDiag = GPIO_GET(MOTOR_DIAG_PORT_2, MOTOR_DIAG_PIN_2); }
+#endif
+    return motorStep_t_Group[channel].motorDiag;
+}
 
 
 /**
  * @brief   start motor with direction set
  * @param   dir direction to move
  * @param   speed direction to move
+ * @param   channel motor channel
  */
-void MotorStart(uint8_t dir, uint32_t speed)
+void MotorStart(uint8_t dir, uint32_t speed, uint8_t channel)
 {
-    if(dir == MOTOR_DIR_IN)
-        MOTOR_DIR_SET_IN;
-    else if(dir == MOTOR_DIR_OUT)
-        MOTOR_DIR_SET_OUT;
-    MOTOR_EN_SET_ENABLE;
-    PwmFreqSet(speed, Motor_Channel);
-#ifdef __DEBUG_MOTOR_STEP_ATY
-    printf("\r\nMotor Start: %d - %d", dir, speed);
-#endif /* __DEBUG_MOTOR_STEP_ATY */
+    MotorSetDirection(dir, channel);
+    MotorSetAble(1, channel);
+#if (MOTOR_COUNT >= 1)
+    if(channel == 0){ PwmFreqSet(speed, MOTOR_PWM_Channel_0); }
+#endif
+#if (MOTOR_COUNT >= 2)
+    if(channel == 1){ PwmFreqSet(speed, MOTOR_PWM_Channel_1); }
+#endif
+#if (MOTOR_COUNT >= 3)
+    if(channel == 2){ PwmFreqSet(speed, MOTOR_PWM_Channel_2); }
+#endif
 }
 
 /**
  * @brief   start motor with only speed
  * @param   speed direction to move
+ * @param   channel motor channel
  */
-void MotorStartSpeed(uint32_t speed)
+void MotorStartSpeed(uint32_t speed, uint8_t channel)
 {
-    MOTOR_EN_SET_ENABLE;
-    PwmFreqSet(speed, Motor_Channel);
-#ifdef __DEBUG_MOTOR_STEP_ATY
-    printf("\r\nMotor Start: %d", speed);
-#endif /* __DEBUG_MOTOR_STEP_ATY */
+    MotorSetAble(1, channel);
+#if (MOTOR_COUNT >= 1)
+    if(channel == 0){ PwmFreqSet(speed, MOTOR_PWM_Channel_0); }
+#endif
+#if (MOTOR_COUNT >= 2)
+    if(channel == 1){ PwmFreqSet(speed, MOTOR_PWM_Channel_0); }
+#endif
+#if (MOTOR_COUNT >= 3)
+    if(channel == 2){ PwmFreqSet(speed, MOTOR_PWM_Channel_0); }
+#endif
 }
 
 /**
  * @brief   stop motor
+ * @param   channel motor channel
  */
-void MotorStop(void)
+void MotorStop(uint8_t channel)
 {
     // MOTOR_PARAM_SET(MOTOR_DIR_OUT, 0, 0, 0, 0, motorSetState);
-    if(motorEn == 0)
+    if(motorStep_t_Group[channel].motorEn == 0)
         return;
     else{
-        PWM_Stop(0, Motor_Channel);
-        MOTOR_EN_SET_DISABLE;
-        motorStartCounter = 0;
-        motorStopCounter = 0;
-#ifdef __DEBUG_MOTOR_STEP_ATY
-        printf("\r\nMotor Stop");
-#endif /* __DEBUG_MOTOR_STEP_ATY */
+#if (MOTOR_COUNT >= 1)
+        if(channel == 0){ PWM_Stop(0, MOTOR_PWM_Channel_0); }
+#endif
+#if (MOTOR_COUNT >= 2)
+        if(channel == 1){ PWM_Stop(0, MOTOR_PWM_Channel_0); }
+#endif
+#if (MOTOR_COUNT >= 3)
+        if(channel == 2){ PWM_Stop(0, MOTOR_PWM_Channel_0); }
+#endif
+        MotorSetAble(0, channel);;
+        motorStep_t_Group[channel].motorSpeedCounter = 0;
+        motorStep_t_Group[channel].motorStopCounter = 0;
     }
 }
 
 /**
  * @brief   process motor error
+ * @param   channel motor channel
  * @note    put at 1ms cycle
  */
-void MotorSelfCycle(void)
+void MotorSelfCycle(uint8_t channel)
 {
-    if(MOTOR_DIAG_GET_H)
-    {
-        if(motorEn == 1)
-            MOTOR_EN_SET_DISABLE;
-        if(motorStopCounter >= 100)
-            MOTOR_EN_SET_ENABLE;
+    if(MotorGetDiagLevel(channel)){
+        if(motorStep_t_Group[channel].motorEn == 1)
+            MotorSetAble(0, channel);
+        if(motorStep_t_Group[channel].motorStopCounter >= 10000)
+            MotorSetAble(1, channel);;
     }
 }
 
@@ -129,92 +237,271 @@ void MotorSelfCycle(void)
  * @brief   deal step motor state
  * @note    put at 1ms cycle;
  *          set motorSetState = 4 to change motor dir with speed no change
- *          set motorSetState = 3 to start motor directly, motorSoftTime need to be 0
- *          set motorSetState = 2 to strat motor with soft, motorDir/motorSoftSpeed/motorSpeed/motorSoftTime/motorTime need to be set
+ *          set motorSetState = 3 to start motor directly, motorSoftSteps need to be 0
+ *          set motorSetState = 2 to strat motor with soft, motorDir/motorSoftSpeed/motorSpeed/motorSoftSteps/motorSteps need to be set
  *          set motorSetState = 0 to stop motor
  *          set motorSetState = 10 to scram motor
  *          when motorSetState = 5 means last cycle finished, set others to start a new cycle
  *          when motorSetState = 1 means motor running and state not changing
  */
-void MotorStateMachine_Step(void)
+void MotorStateMachine_Step_PWM(void)
 {
-    if(motorSoftSpeed < motorSpeed)
-        motorSoftSpeed = motorSpeed;
-
-    if(motorSetState == 4){
-        motorStartCounter = 0;
-        motorStopCounter = 0;
-        motorSetState = 2;
-        motorDir = !motorDir;
-    }
-    else if(motorSetState == 3){
-        motorStartCounter = motorSoftTime;
-        motorSetState = 1;
-        MotorStart(motorDir, motorSpeed);
-    }
-    else if(motorSetState == 2){
-        motorStartCounter = 0;
-        motorSetState = 1;
-        MotorStart(motorDir, motorSoftSpeed);
-    }
-    else if(motorSetState == 1){
-        if(motorStartCounter < motorSoftTime){
+    uint8_t i = 0;
+    for(i = 0; i < MOTOR_COUNT; i++){
+        if(motorStep_t_Group[i].motorSoftSpeed < motorStep_t_Group[i].motorSpeed)
+            motorStep_t_Group[i].motorSoftSpeed = motorStep_t_Group[i].motorSpeed;
+
+        if(motorStep_t_Group[i].motorSetState == 4){
+            motorStep_t_Group[i].motorStopCounter = 0;
+            motorStep_t_Group[i].motorStepCounter = 0;
+            motorStep_t_Group[i].motorSetState = 2;
+            motorStep_t_Group[i].motorDir = !motorStep_t_Group[i].motorDir;
+        }
+        else if(motorStep_t_Group[i].motorSetState == 3){
+            motorStep_t_Group[i].motorStepCounter = motorStep_t_Group[i].motorSoftSteps;
+            MotorStart(motorStep_t_Group[i].motorDir, motorStep_t_Group[i].motorSpeed, i);
+            motorStep_t_Group[i].motorSetState = 1;
+        }
+        else if(motorStep_t_Group[i].motorSetState == 2){
+            motorStep_t_Group[i].motorStepCounter = 0;
+            MotorStart(motorStep_t_Group[i].motorDir, motorStep_t_Group[i].motorSoftSpeed, i);
+            motorStep_t_Group[i].motorSetState = 1;
+        }
+        else if(motorStep_t_Group[i].motorSetState == 1){
+            if(motorStep_t_Group[i].motorStepCounter < motorStep_t_Group[i].motorSoftSteps){
 #if defined (Motor_StartLine_T)
-            speedIncreaseStep = ((float)(motorSoftSpeed - motorSpeed) / (float)motorSoftTime);  // at 1ms cycle
-            MotorStart(motorDir,
-                motorSpeed < (motorSoftSpeed - (speedIncreaseStep * motorStartCounter)) ?
-                (motorSoftSpeed - (speedIncreaseStep * motorStartCounter)) : motorSpeed);
+                motorStep_t_Group[i].speedIncreaseStep = ((float)(motorStep_t_Group[i].motorSoftSpeed - motorStep_t_Group[i].motorSpeed) / (float)motorStep_t_Group[i].motorSoftSteps);  // at 1ms cycle
+                MotorStart(motorStep_t_Group[i].motorDir,
+                    motorStep_t_Group[i].motorSpeed < (motorStep_t_Group[i].motorSoftSpeed - (motorStep_t_Group[i].speedIncreaseStep * motorStep_t_Group[i].motorStepCounter)) ?
+                    (motorStep_t_Group[i].motorSoftSpeed - (motorStep_t_Group[i].speedIncreaseStep * motorStep_t_Group[i].motorStepCounter)) : motorStep_t_Group[i].motorSpeed, i);
 #elif defined (Motor_StartLine_S)
-            // S line: y = ax^3 + cx, a in 0-1, c >= 0, lower c cause lower increase at start or end, c for users
-            S_paramA = (((float)(motorSoftSpeed - motorSpeed) / 2)
-                - (S_paramC * (float)((float)motorSoftTime / 2) * (float)((float)motorSoftTime / 2) / 2))
-                / ((float)((float)motorSoftTime / 2) * (float)((float)motorSoftTime / 2)
-                    * (float)((float)motorSoftTime / 2) * (float)((float)motorSoftTime / 2)) * 4;
-            // mbG[27] = S_paramA * 10000000;
-            if(motorStartCounter < (motorSoftTime / 2))
-                speedIncreaseStep =
-                ((float)(S_paramA * motorStartCounter * motorStartCounter * motorStartCounter * motorStartCounter) / 4)
-                + ((float)(S_paramC * motorStartCounter * motorStartCounter) / 2);
-            // (S_paramA * motorStartCounter * motorStartCounter * motorStartCounter)
-            // + (S_paramC * motorStartCounter);
-            else
-                speedIncreaseStep =
-                (float)((float)(motorSoftSpeed - motorSpeed) / 2)
-                + ((float)(S_paramA * motorSoftTime * motorSoftTime * motorSoftTime * motorSoftTime) / 64)
-                + ((float)(S_paramC * motorSoftTime * motorSoftTime) / 8)
-                - ((float)(S_paramA * (motorSoftTime - motorStartCounter) * (motorSoftTime - motorStartCounter)
-                    * (motorSoftTime - motorStartCounter) * (motorSoftTime - motorStartCounter)) / 4)
-                - ((float)(S_paramC * (motorSoftTime - motorStartCounter) * (motorSoftTime - motorStartCounter)) / 2);
-                // 0
-                // - (S_paramA * (float)((float)motorStartCounter - (float)motorSoftTime)
-                //     * (float)((float)motorStartCounter - (float)motorSoftTime)
-                //     * (float)((float)motorStartCounter - (float)motorSoftTime))
-                // - (S_paramC * (float)((float)motorStartCounter - (float)motorSoftTime));
-            MotorStart(motorDir,
-                motorSpeed < (motorSoftSpeed - speedIncreaseStep) ?
-                (motorSoftSpeed - speedIncreaseStep) : motorSpeed);
+                // S line: y = ax^3 + cx, a in 0-1, c >= 0, lower c cause lower increase at start or end, c for users
+                motorStep_t_Group[i].S_paramA = (((float)(motorStep_t_Group[i].motorSoftSpeed - motorStep_t_Group[i].motorSpeed) / 2)
+                    - (motorStep_t_Group[i].S_paramC * (float)((float)motorStep_t_Group[i].motorSoftSteps / 2) * (float)((float)motorStep_t_Group[i].motorSoftSteps / 2) / 2))
+                    / ((float)((float)motorStep_t_Group[i].motorSoftSteps / 2) * (float)((float)motorStep_t_Group[i].motorSoftSteps / 2)
+                        * (float)((float)motorStep_t_Group[i].motorSoftSteps / 2) * (float)((float)motorStep_t_Group[i].motorSoftSteps / 2)) * 4;
+                // mbG[27] = motorStep_t_Group[i].S_paramA * 10000000;
+                if(motorStep_t_Group[i].motorStepCounter < (motorStep_t_Group[i].motorSoftSteps / 2))
+                    motorStep_t_Group[i].speedIncreaseStep =
+                    ((float)(motorStep_t_Group[i].S_paramA * motorStep_t_Group[i].motorStepCounter * motorStep_t_Group[i].motorStepCounter * motorStep_t_Group[i].motorStepCounter * motorStep_t_Group[i].motorStepCounter) / 4)
+                    + ((float)(motorStep_t_Group[i].S_paramC * motorStep_t_Group[i].motorStepCounter * motorStep_t_Group[i].motorStepCounter) / 2);
+                // (motorStep_t_Group[i].S_paramA * motorStep_t_Group[i].motorStepCounter * motorStep_t_Group[i].motorStepCounter * motorStep_t_Group[i].motorStepCounter)
+                // + (motorStep_t_Group[i].S_paramC * motorStep_t_Group[i].motorStepCounter);
+                else
+                    motorStep_t_Group[i].speedIncreaseStep =
+                    (float)((float)(motorStep_t_Group[i].motorSoftSpeed - motorStep_t_Group[i].motorSpeed) / 2)
+                    + ((float)(motorStep_t_Group[i].S_paramA * motorStep_t_Group[i].motorSoftSteps * motorStep_t_Group[i].motorSoftSteps * motorStep_t_Group[i].motorSoftSteps * motorStep_t_Group[i].motorSoftSteps) / 64)
+                    + ((float)(motorStep_t_Group[i].S_paramC * motorStep_t_Group[i].motorSoftSteps * motorStep_t_Group[i].motorSoftSteps) / 8)
+                    - ((float)(motorStep_t_Group[i].S_paramA * (motorStep_t_Group[i].motorSoftSteps - motorStep_t_Group[i].motorStepCounter) * (motorStep_t_Group[i].motorSoftSteps - motorStep_t_Group[i].motorStepCounter)
+                        * (motorStep_t_Group[i].motorSoftSteps - motorStep_t_Group[i].motorStepCounter) * (motorStep_t_Group[i].motorSoftSteps - motorStep_t_Group[i].motorStepCounter)) / 4)
+                    - ((float)(motorStep_t_Group[i].S_paramC * (motorStep_t_Group[i].motorSoftSteps - motorStep_t_Group[i].motorStepCounter) * (motorStep_t_Group[i].motorSoftSteps - motorStep_t_Group[i].motorStepCounter)) / 2);
+                    // 0
+                    // - (motorStep_t_Group[i].S_paramA * (float)((float)motorStep_t_Group[i].motorStepCounter - (float)motorStep_t_Group[i].motorSoftSteps)
+                    //     * (float)((float)motorStep_t_Group[i].motorStepCounter - (float)motorStep_t_Group[i].motorSoftSteps)
+                    //     * (float)((float)motorStep_t_Group[i].motorStepCounter - (float)motorStep_t_Group[i].motorSoftSteps))
+                    // - (motorStep_t_Group[i].S_paramC * (float)((float)motorStep_t_Group[i].motorStepCounter - (float)motorStep_t_Group[i].motorSoftSteps));
+                MotorStart(motorStep_t_Group[i].motorDir,
+                    motorStep_t_Group[i].motorSpeed < (motorStep_t_Group[i].motorSoftSpeed - motorStep_t_Group[i].speedIncreaseStep) ?
+                    (motorStep_t_Group[i].motorSoftSpeed - motorStep_t_Group[i].speedIncreaseStep) : motorStep_t_Group[i].motorSpeed, i);
 #else
 #endif
+            }
+
+            if(motorStep_t_Group[i].motorStepCounter == motorStep_t_Group[i].motorSoftSteps)
+                motorStep_t_Group[i].motorSetState = 3;
+            else if(motorStep_t_Group[i].motorStepCounter == (motorStep_t_Group[i].motorSoftSteps + motorStep_t_Group[i].motorSteps))
+                motorStep_t_Group[i].motorSetState = 5;
         }
+        else if(motorStep_t_Group[i].motorSetState == 10){
+            MotorStop(i);
+            motorStep_t_Group[i].motorSetState = 0;
+        }
+        else{ MotorStop(i); }    // 5 0
 
-        if(motorStartCounter == motorSoftTime)
-            motorSetState = 3;
-        else if(motorStartCounter == (motorSoftTime + motorTime))
-            motorSetState = 5;
-    }
-    else if(motorSetState == 10){
-        motorSetState = 0;
-        MotorStop();
+        if(motorStep_t_Group[i].motorEn == 0){
+            motorStep_t_Group[i].motorStepCounter = 0;
+            motorStep_t_Group[i].motorStopCounter++;
+        }
+        else{
+            motorStep_t_Group[i].motorStepCounter++;
+            motorStep_t_Group[i].motorStopCounter = 0;
+        }
     }
-    else{ MotorStop(); }    // 5 0
+}
 
-    if(motorEn == 0){
-        motorStartCounter = 0;
-        motorStopCounter++;
-    }
-    else{
-        motorStartCounter++;
-        motorStopCounter = 0;
+
+uint8_t motorLastState[2] = {0};
+/**
+ * @brief   deal step motor state
+ * @note    put at 1us cycle;
+ *          set motorSetState = 4 to change motor dir with speed no change
+ *          set motorSetState = 3 to start motor directly, motorSoftSteps need to be 0
+ *          set motorSetState = 2 to strat motor with soft, motorDir/motorSoftSpeed/motorSpeed/motorSoftSteps/motorSteps need to be set
+ *          set motorSetState = 0 to stop motor
+ *          set motorSetState = 10 to scram motor
+ *          when motorSetState = 5 means last cycle finished, set others to start a new cycle
+ *          when motorSetState = 1 means motor running and state not changing
+ */
+void MotorStateMachine_Step(void)
+{
+    uint8_t i = 0;
+    for(i = 0; i < MOTOR_COUNT; i++){
+        if(motorStep_t_Group[i].motorSoftSpeed < motorStep_t_Group[i].motorSpeed)
+            motorStep_t_Group[i].motorSoftSpeed = motorStep_t_Group[i].motorSpeed;
+
+        if(motorStep_t_Group[i].motorSetState == 4){
+            motorStep_t_Group[i].motorSpeedCounter = 0;
+            motorStep_t_Group[i].motorStepCounter = 0;
+            motorStep_t_Group[i].motorSetState = 2;
+            motorStep_t_Group[i].motorDir = !motorStep_t_Group[i].motorDir;
+        }
+        else if(motorStep_t_Group[i].motorSetState == 3){
+            motorStep_t_Group[i].motorEn = 1;
+            motorStep_t_Group[i].motorSpeedCounter = 0;
+            motorStep_t_Group[i].motorStepCounter = 0;
+            motorLastState[i] = 3;
+            motorStep_t_Group[i].motorSetState = 1;
+        }
+        else if(motorStep_t_Group[i].motorSetState == 2){
+            motorStep_t_Group[i].motorEn = 1;
+            motorStep_t_Group[i].motorSpeedCounter = 0;
+            motorStep_t_Group[i].motorStepCounter = 0;
+            motorLastState[i] = 2;
+            motorStep_t_Group[i].motorSetState = 1;
+        }
+        else if(motorStep_t_Group[i].motorSetState == 1){
+        }
+        else if(motorStep_t_Group[i].motorSetState == 10){
+            motorStep_t_Group[i].motorEn = 0;
+            motorStep_t_Group[i].motorSetState = 0;
+        }
+        else{   // 5 0
+            motorStep_t_Group[i].motorEn = 0;
+            motorStep_t_Group[i].motorSetState = 0;
+        }
+
+
+//         if(motorStep_t_Group[i].motorSetState == 4){
+//             motorStep_t_Group[i].motorSpeedCounter = 0;
+//             motorStep_t_Group[i].motorStopCounter = 0;
+//             motorStep_t_Group[i].motorSetState = 2;
+//             motorStep_t_Group[i].motorDir = !motorStep_t_Group[i].motorDir;
+//         }
+//         else if(motorStep_t_Group[i].motorSetState == 3){
+//             motorStep_t_Group[i].motorSpeedCounter = motorStep_t_Group[i].motorSoftSteps;
+//             MotorStart(motorStep_t_Group[i].motorDir, motorStep_t_Group[i].motorSpeed, i);
+//             motorStep_t_Group[i].motorSetState = 1;
+//         }
+//         else if(motorStep_t_Group[i].motorSetState == 2){
+//             motorStep_t_Group[i].motorSpeedCounter = 0;
+//             MotorStart(motorStep_t_Group[i].motorDir, motorStep_t_Group[i].motorSoftSpeed, i);
+//             motorStep_t_Group[i].motorSetState = 1;
+//         }
+//         else if(motorStep_t_Group[i].motorSetState == 1){
+//             if(motorStep_t_Group[i].motorSpeedCounter < motorStep_t_Group[i].motorSoftSteps){
+// #if defined (Motor_StartLine_T)
+//                 motorStep_t_Group[i].speedIncreaseStep = ((float)(motorStep_t_Group[i].motorSoftSpeed - motorStep_t_Group[i].motorSpeed) / (float)motorStep_t_Group[i].motorSoftSteps);  // at 1ms cycle
+//                 MotorStart(motorStep_t_Group[i].motorDir,
+//                     motorStep_t_Group[i].motorSpeed < (motorStep_t_Group[i].motorSoftSpeed - (motorStep_t_Group[i].speedIncreaseStep * motorStep_t_Group[i].motorSpeedCounter)) ?
+//                     (motorStep_t_Group[i].motorSoftSpeed - (motorStep_t_Group[i].speedIncreaseStep * motorStep_t_Group[i].motorSpeedCounter)) : motorStep_t_Group[i].motorSpeed, i);
+// #elif defined (Motor_StartLine_S)
+//             // S line: y = ax^3 + cx, a in 0-1, c >= 0, lower c cause lower increase at start or end, c for users
+//                 motorStep_t_Group[i].S_paramA = (((float)(motorStep_t_Group[i].motorSoftSpeed - motorStep_t_Group[i].motorSpeed) / 2)
+//                     - (motorStep_t_Group[i].S_paramC * (float)((float)motorStep_t_Group[i].motorSoftSteps / 2) * (float)((float)motorStep_t_Group[i].motorSoftSteps / 2) / 2))
+//                     / ((float)((float)motorStep_t_Group[i].motorSoftSteps / 2) * (float)((float)motorStep_t_Group[i].motorSoftSteps / 2)
+//                         * (float)((float)motorStep_t_Group[i].motorSoftSteps / 2) * (float)((float)motorStep_t_Group[i].motorSoftSteps / 2)) * 4;
+//                 // mbG[27] = motorStep_t_Group[i].S_paramA * 10000000;
+//                 if(motorStep_t_Group[i].motorSpeedCounter < (motorStep_t_Group[i].motorSoftSteps / 2))
+//                     motorStep_t_Group[i].speedIncreaseStep =
+//                     ((float)(motorStep_t_Group[i].S_paramA * motorStep_t_Group[i].motorSpeedCounter * motorStep_t_Group[i].motorSpeedCounter * motorStep_t_Group[i].motorSpeedCounter * motorStep_t_Group[i].motorSpeedCounter) / 4)
+//                     + ((float)(motorStep_t_Group[i].S_paramC * motorStep_t_Group[i].motorSpeedCounter * motorStep_t_Group[i].motorSpeedCounter) / 2);
+//                 // (motorStep_t_Group[i].S_paramA * motorStep_t_Group[i].motorSpeedCounter * motorStep_t_Group[i].motorSpeedCounter * motorStep_t_Group[i].motorSpeedCounter)
+//                 // + (motorStep_t_Group[i].S_paramC * motorStep_t_Group[i].motorSpeedCounter);
+//                 else
+//                     motorStep_t_Group[i].speedIncreaseStep =
+//                     (float)((float)(motorStep_t_Group[i].motorSoftSpeed - motorStep_t_Group[i].motorSpeed) / 2)
+//                     + ((float)(motorStep_t_Group[i].S_paramA * motorStep_t_Group[i].motorSoftSteps * motorStep_t_Group[i].motorSoftSteps * motorStep_t_Group[i].motorSoftSteps * motorStep_t_Group[i].motorSoftSteps) / 64)
+//                     + ((float)(motorStep_t_Group[i].S_paramC * motorStep_t_Group[i].motorSoftSteps * motorStep_t_Group[i].motorSoftSteps) / 8)
+//                     - ((float)(motorStep_t_Group[i].S_paramA * (motorStep_t_Group[i].motorSoftSteps - motorStep_t_Group[i].motorSpeedCounter) * (motorStep_t_Group[i].motorSoftSteps - motorStep_t_Group[i].motorSpeedCounter)
+//                         * (motorStep_t_Group[i].motorSoftSteps - motorStep_t_Group[i].motorSpeedCounter) * (motorStep_t_Group[i].motorSoftSteps - motorStep_t_Group[i].motorSpeedCounter)) / 4)
+//                     - ((float)(motorStep_t_Group[i].S_paramC * (motorStep_t_Group[i].motorSoftSteps - motorStep_t_Group[i].motorSpeedCounter) * (motorStep_t_Group[i].motorSoftSteps - motorStep_t_Group[i].motorSpeedCounter)) / 2);
+//                     // 0
+//                     // - (motorStep_t_Group[i].S_paramA * (float)((float)motorStep_t_Group[i].motorSpeedCounter - (float)motorStep_t_Group[i].motorSoftSteps)
+//                     //     * (float)((float)motorStep_t_Group[i].motorSpeedCounter - (float)motorStep_t_Group[i].motorSoftSteps)
+//                     //     * (float)((float)motorStep_t_Group[i].motorSpeedCounter - (float)motorStep_t_Group[i].motorSoftSteps))
+//                     // - (motorStep_t_Group[i].S_paramC * (float)((float)motorStep_t_Group[i].motorSpeedCounter - (float)motorStep_t_Group[i].motorSoftSteps));
+//                 MotorStart(motorStep_t_Group[i].motorDir,
+//                     motorStep_t_Group[i].motorSpeed < (motorStep_t_Group[i].motorSoftSpeed - motorStep_t_Group[i].speedIncreaseStep) ?
+//                     (motorStep_t_Group[i].motorSoftSpeed - motorStep_t_Group[i].speedIncreaseStep) : motorStep_t_Group[i].motorSpeed, i);
+// #else
+// #endif
+//             }
+
+//             if(motorStep_t_Group[i].motorSpeedCounter == motorStep_t_Group[i].motorSoftSteps)
+//                 motorStep_t_Group[i].motorSetState = 3;
+//             else if(motorStep_t_Group[i].motorSpeedCounter == (motorStep_t_Group[i].motorSoftSteps + motorStep_t_Group[i].motorSteps))
+//                 motorStep_t_Group[i].motorSetState = 5;
+//         }
+//         else if(motorStep_t_Group[i].motorSetState == 10){
+//             MotorStop(i);
+//             motorStep_t_Group[i].motorSetState = 0;
+//         }
+//         else{ MotorStop(i); }    // 5 0
+
+//         if(motorStep_t_Group[i].motorEn == 0){
+//             motorStep_t_Group[i].motorSpeedCounter = 0;
+//             motorStep_t_Group[i].motorStopCounter++;
+//         }
+//         else{
+//             motorStep_t_Group[i].motorSpeedCounter--;
+//             if(motorStep_t_Group[i].motorSpeedCounter == 0){
+//                 motorStep_t_Group[i].motorSpeedCounter = 0;
+//                 motorStep_t_Group[i].motorStepCounter++;
+//             }
+//             motorStep_t_Group[i].motorStopCounter = 0;
+//         }
+
+        if(motorStep_t_Group[i].motorEn){
+            motorStep_t_Group[i].motorStopCounter = 0;
+            MotorSetDirection(motorStep_t_Group[i].motorDir, i);
+            MotorSetAble(motorStep_t_Group[i].motorEn, i);
+            motorStep_t_Group[i].motorSpeedCounter++;
+            mbP_HSTV = motorStep_t_Group[i].motorSpeedCounter;
+
+            if((motorLastState[i] == 3 && motorStep_t_Group[i].motorSpeedCounter >= motorStep_t_Group[i].motorSpeed)
+                || (motorLastState[i] == 2 && motorStep_t_Group[i].motorSpeedCounter >= motorStep_t_Group[i].motorSoftSpeed)){
+                motorStep_t_Group[i].motorSpeedCounter = 0;
+                motorStep_t_Group[i].motorStepLevel = !motorStep_t_Group[i].motorStepLevel;
+                MotorSetStepLevel(motorStep_t_Group[i].motorStepLevel, i);
+                mbP_HSHS = motorStep_t_Group[i].motorStepLevel;
+                mbP_HSTW = motorStep_t_Group[i].motorStepCounter;
+
+                if(motorStep_t_Group[i].motorStepLevel == STATIC_STEP_LEVEL){
+                    motorStep_t_Group[i].motorStepCounter++;
+
+                    if((motorLastState[i] == 3 && motorStep_t_Group[i].motorStepCounter >= motorStep_t_Group[i].motorSteps)
+                        || (motorLastState[i] == 2 && motorStep_t_Group[i].motorStepCounter >= motorStep_t_Group[i].motorSoftSteps)){
+                        motorStep_t_Group[i].motorSpeedCounter = 0;
+                        motorStep_t_Group[i].motorStepCounter = 0;
+                        motorStep_t_Group[i].motorStepLevel = STATIC_STEP_LEVEL;
+                        MotorSetStepLevel(motorStep_t_Group[i].motorStepLevel, i);
+                        // motorStep_t_Group[i].motorSpeedCounter = 0;
+                        if(motorLastState[i] == 3)
+                            motorStep_t_Group[i].motorSetState = 5;
+                        else if(motorLastState[i] == 2)
+                            motorStep_t_Group[i].motorSetState = 3;
+                    }
+                }
+            }
+        }
+        else{
+            motorStep_t_Group[i].motorSpeedCounter = 0;
+            motorStep_t_Group[i].motorStepCounter = 0;
+            motorStep_t_Group[i].motorStopCounter++;
+            motorStep_t_Group[i].motorStepLevel = STATIC_STEP_LEVEL;
+            MotorSetStepLevel(motorStep_t_Group[i].motorStepLevel, i);
+            MotorSetAble(motorStep_t_Group[i].motorEn, i);
+        }
     }
 }
 

+ 88 - 58
MOTOR_STEP_ATY.h

@@ -42,72 +42,102 @@
 // #define Motor_StartLine_2
 #define Motor_StartLine_T
 // #define Motor_StartLine_S
-#define Motor_Channel PWM_CHANNEL_8P
-
+// #define Motor_Channel PWM_T2C2
+
+// 3 max, if need more, add codes at every function
+#define MOTOR_COUNT 2
+
+// pin defination must include all motors
+// diag pin is selectable
+#define MOTOR_EN_PORT_0               0
+#define MOTOR_EN_PIN_0                P37
+#define MOTOR_DIR_PORT_0              0
+#define MOTOR_DIR_PIN_0               P21
+#define MOTOR_STEP_PORT_0             0
+#define MOTOR_STEP_PIN_0              P23
+#define MOTOR_DIAG_PORT_0             0
+#define MOTOR_DIAG_PIN_0              0
+#define MOTOR_PWM_Channel_0           PWM_CHANNEL_8P
+
+#define MOTOR_EN_PORT_1               0
+#define MOTOR_EN_PIN_1                P36
+#define MOTOR_DIR_PORT_1              0
+#define MOTOR_DIR_PIN_1               P20
+#define MOTOR_STEP_PORT_1             0
+#define MOTOR_STEP_PIN_1              P22
+#define MOTOR_DIAG_PORT_1             0
+#define MOTOR_DIAG_PIN_1              0
+#define MOTOR_PWM_Channel_1           PWM_CHANNEL_7P
+
+#define STATIC_STEP_LEVEL 0
 /******************************************************************************/
 
-extern uint8_t motorEn;
-extern uint8_t motorDir;
-extern uint32_t motorSoftSpeed;
-extern uint32_t motorSpeed;
-extern uint32_t motorSoftTime;
-extern uint32_t motorTime;
-
-extern uint32_t motorStartCounter;
-extern uint32_t motorStopCounter;       // for stall detection or driver error(TMC2209)
-
-extern uint8_t motorSetState;           // 0: stop, 1: start hold, 2: start soft, 3: run speed, 4: change dir, 5: stop state, soft set 0 after use
-
-
-#define MOTOR_EN_SET_ENABLE \
-    do{GPIO_SET_L(MOTOR_EN_PORT, MOTOR_EN_PIN); motorEn = 1;}while(0)
-
-#define MOTOR_EN_SET_DISABLE \
-    do{GPIO_SET_H(MOTOR_EN_PORT, MOTOR_EN_PIN); motorEn = 0;}while(0)
-
-#define MOTOR_DIR_OUT       0
-#define MOTOR_DIR_IN        1
-#define MOTOR_DIR_SET_IN \
-    do{ \
-        if(MOTOR_DIR_IN) \
-            GPIO_SET_H(MOTOR_DIR_PORT, MOTOR_DIR_PIN); \
-        else \
-            GPIO_SET_L(MOTOR_DIR_PORT, MOTOR_DIR_PIN); \
-        motorDir = MOTOR_DIR_IN; \
-    }while(0)
-#define MOTOR_DIR_SET_OUT \
-    do{ \
-        if(MOTOR_DIR_OUT) \
-            GPIO_SET_H(MOTOR_DIR_PORT, MOTOR_DIR_PIN); \
-        else \
-            GPIO_SET_L(MOTOR_DIR_PORT, MOTOR_DIR_PIN); \
-        motorDir = MOTOR_DIR_OUT; \
-    }while(0)
-
-#define MOTOR_STEP_SET_H \
-    (GPIO_SET_H(MOTOR_STEP_PORT, MOTOR_STEP_PIN))
-#define MOTOR_STEP_SET_L \
-    (GPIO_SET_L(MOTOR_STEP_PORT, MOTOR_STEP_PIN))
-
-#define MOTOR_DIAG_GET_H (GPIO_GET_H(MOTOR_DIAG_PORT, MOTOR_DIAG_PIN))
-#define MOTOR_DIAG_GET_L (GPIO_GET_L(MOTOR_DIAG_PORT, MOTOR_DIAG_PIN))
-
-#define MOTOR_PARAM_SET(dir, softSpeed, speed, softTime, time, setState) \
+typedef struct{
+    uint8_t motorEn;
+    uint8_t motorDir;
+    uint8_t motorStepLevel;
+    uint8_t motorDiag;
+
+    uint32_t motorSoftSpeed;
+    uint32_t motorSpeed;
+    uint32_t motorSpeedCounter;
+
+    uint32_t motorSoftSteps;
+    uint32_t motorSteps;
+    uint32_t motorStepCounter;
+
+    uint32_t motorStopCounter;      // delay for stall detection or driver error(TMC2209)
+
+    uint8_t motorSetState;          // 0: stop, 1: start hold, 2: start soft, 3: run speed, 4: change dir, 5: stop state, soft set 0 after use, 10: scram motor
+
+    float speedIncreaseStep;
+    float S_paramA;
+#ifdef S_PARAM_C
+    float S_paramC;
+#else
+    float S_paramC;
+#endif
+}motorStep_t;
+
+extern motorStep_t motorStep_t_Group[MOTOR_COUNT];
+
+
+#define MOTOR_PARAM_SET(dir, softSpeed, speed, softSteps, steps, setState, channel) \
     do \
     { \
-        motorDir = (uint8_t)dir; \
-        motorSoftSpeed = (uint32_t)softSpeed; \
-        motorSpeed = (uint32_t)speed; \
-        motorSoftTime = (uint32_t)softTime; \
-        motorTime = (uint32_t)time; \
-        motorSetState = (uint8_t)setState; \
+        motorStep_t_Group[channel].motorDir = (uint8_t)dir; \
+        motorStep_t_Group[channel].motorSoftSpeed = (uint32_t)softSpeed; \
+        motorStep_t_Group[channel].motorSpeed = (uint32_t)speed; \
+        motorStep_t_Group[channel].motorSoftSteps = (uint32_t)softSteps; \
+        motorStep_t_Group[channel].motorSteps = (uint32_t)steps; \
+        motorStep_t_Group[channel].motorSetState = (uint8_t)setState; \
     } while(0)
 
+#define MOTOR_PARAM_GET(dir, softSpeed, speed, softSteps, steps, setState, channel) \
+    do \
+    { \
+        dir = motorStep_t_Group[(uint8_t)channel].motorDir; \
+        softSpeed = motorStep_t_Group[(uint8_t)channel].motorSoftSpeed; \
+        speed = motorStep_t_Group[(uint8_t)channel].motorSpeed; \
+        softSteps = motorStep_t_Group[(uint8_t)channel].motorSoftSteps; \
+        steps = motorStep_t_Group[(uint8_t)channel].motorSteps; \
+        setState = motorStep_t_Group[(uint8_t)channel].motorSetState; \
+    } while(0)
+
+#define MOTOR_DIR_IN 1
+#define MOTOR_DIR_OUT 0
+
+void MotorSetAble(uint8_t enable, uint8_t channel);
+void MotorSetDirection(uint8_t dir, uint8_t channel);
+void MotorSetStepLevel(uint8_t level, uint8_t channel);
+uint8_t MotorGetDiagLevel(uint8_t channel);
+
 
-void MotorStart(uint8_t dir, uint32_t speed);
-void MotorStartSpeed(uint32_t speed);
-void MotorStop(void);
+void MotorStart(uint8_t dir, uint32_t speed, uint8_t channel);
+void MotorStartSpeed(uint32_t speed, uint8_t channel);
+void MotorStop(uint8_t channel);
 void MotorStateMachine_Step(void);
+void MotorStateMachine_Step_PWM(void);
 
 
 #endif /* __MOTOR_STEP_ATY_H */

+ 0 - 0
STM32_HAL_PRINTF_ATY.c → NoPublic/STM32_HAL_PRINTF_ATY.c


+ 0 - 0
STM32_HAL_PRINTF_ATY.h → NoPublic/STM32_HAL_PRINTF_ATY.h


+ 555 - 0
NoPublic/ad7124.c

@@ -0,0 +1,555 @@
+/***************************************************************************//**
+*   @file    ad7124.c
+*   @brief   AD7124 implementation file.
+*   	     Devices: AD7124-4, AD7124-8
+*
+********************************************************************************
+* Copyright 2015-2019(c) Analog Devices, Inc.
+*
+* All rights reserved.
+*
+* 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 Analog Devices, Inc. nor the names of its
+*    contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*  - The use of this software may or may not infringe the patent rights
+*    of one or more patent holders.  This license does not release you
+*    from the requirement that you obtain separate licenses from these
+*    patent holders to use this software.
+*  - Use of the software either in source or binary form, must be run
+*    on or directly connected to an Analog Devices Inc. component.
+*
+* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY
+* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+* INTELLECTUAL PROPERTY RIGHTS, 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 Files **********************************/
+/******************************************************************************/
+#include <stdlib.h>
+#include <stdbool.h>
+#include "ad7124.h"
+
+/* Error codes */
+#define INVALID_VAL -1 /* Invalid argument */
+#define COMM_ERR    -2 /* Communication error on receive */
+#define TIMEOUT     -3 /* A timeout has occured */
+
+/*
+ * Post reset delay required to ensure all internal config done
+ * A time of 2ms should be enough based on the data sheet, but 4ms
+ * chosen to provide enough margin, in case mdelay is not accurate.
+ */
+#define AD7124_POST_RESET_DELAY      4
+
+
+/***************************************************************************//**
+ * @brief Reads the value of the specified register without checking if the
+ *        device is ready to accept user requests.
+ *
+ * @param dev   - The handler of the instance of the driver.
+ * @param p_reg - Pointer to the register structure holding info about the
+ *               register to be read. The read value is stored inside the
+ *               register structure.
+ *
+ * @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t ad7124_no_check_read_register(struct ad7124_dev *dev,
+				      struct ad7124_st_reg* p_reg)
+{
+	int32_t ret = 0;
+	uint8_t buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+	uint8_t i = 0;
+	uint8_t check8 = 0, add_status_length = 0;
+	uint8_t msg_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+
+	if(!dev || !p_reg)
+		return INVALID_VAL;
+
+	/* Build the Command word */
+	buffer[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_RD |
+		    AD7124_COMM_REG_RA(p_reg->addr);
+
+	/*
+	 * If this is an AD7124_DATA register read, and the DATA_STATUS bit is set
+	 * in ADC_CONTROL, need to read 4, not 3 bytes for DATA with STATUS
+	 */
+	if ((p_reg->addr == AD7124_DATA_REG) &&
+	    (dev->regs[AD7124_ADC_Control].value & AD7124_ADC_CTRL_REG_DATA_STATUS)) {
+		add_status_length = 1;
+	}
+
+	/* Read data from the device */
+	ret = spi_write_and_read(dev->spi_desc,
+				 buffer,
+				 ((dev->use_crc != AD7124_DISABLE_CRC) ? p_reg->size + 1
+				  : p_reg->size) + 1 + add_status_length);
+	if(ret < 0)
+		return ret;
+
+	/* Check the CRC */
+	if(dev->use_crc == AD7124_USE_CRC) {
+		msg_buf[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_RD |
+			     AD7124_COMM_REG_RA(p_reg->addr);
+		for(i = 1; i < p_reg->size + 2 + add_status_length; ++i) {
+			msg_buf[i] = buffer[i];
+		}
+		check8 = ad7124_compute_crc8(msg_buf, p_reg->size + 2 + add_status_length);
+	}
+
+	if(check8 != 0) {
+		/* ReadRegister checksum failed. */
+		return COMM_ERR;
+	}
+
+	/*
+	 * if reading Data with 4 bytes, need to copy the status byte to the STATUS
+	 * register struct value member
+	 */
+	if (add_status_length) {
+		dev->regs[AD7124_Status].value = buffer[p_reg->size + 1];
+	}
+
+	/* Build the result */
+	p_reg->value = 0;
+	for(i = 1; i < p_reg->size + 1; i++) {
+		p_reg->value <<= 8;
+		p_reg->value += buffer[i];
+	}
+
+	return ret;
+}
+
+/***************************************************************************//**
+ * @brief Writes the value of the specified register without checking if the
+ *        device is ready to accept user requests.
+ *
+ * @param dev - The handler of the instance of the driver.
+ * @param reg - Register structure holding info about the register to be written
+ *
+ * @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t ad7124_no_check_write_register(struct ad7124_dev *dev,
+				       struct ad7124_st_reg reg)
+{
+	int32_t ret = 0;
+	int32_t reg_value = 0;
+	uint8_t wr_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+	uint8_t i = 0;
+	uint8_t crc8 = 0;
+
+	if(!dev)
+		return INVALID_VAL;
+
+	/* Build the Command word */
+	wr_buf[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_WR |
+		    AD7124_COMM_REG_RA(reg.addr);
+
+	/* Fill the write buffer */
+	reg_value = reg.value;
+	for(i = 0; i < reg.size; i++) {
+		wr_buf[reg.size - i] = reg_value & 0xFF;
+		reg_value >>= 8;
+	}
+
+	/* Compute the CRC */
+	if(dev->use_crc != AD7124_DISABLE_CRC) {
+		crc8 = ad7124_compute_crc8(wr_buf, reg.size + 1);
+		wr_buf[reg.size + 1] = crc8;
+	}
+
+	/* Write data to the device */
+	ret = spi_write_and_read(dev->spi_desc,
+				 wr_buf,
+				 (dev->use_crc != AD7124_DISABLE_CRC) ? reg.size + 2
+				 : reg.size + 1);
+
+	return ret;
+}
+
+/***************************************************************************//**
+ * @brief Reads the value of the specified register only when the device is ready
+ *        to accept user requests. If the device ready flag is deactivated the
+ *        read operation will be executed without checking the device state.
+ *
+ * @param dev   - The handler of the instance of the driver.
+ * @param p_reg - Pointer to the register structure holding info about the
+ *               register to be read. The read value is stored inside the
+ *               register structure.
+ *
+ * @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t ad7124_read_register(struct ad7124_dev *dev,
+			     struct ad7124_st_reg* p_reg)
+{
+	int32_t ret;
+
+	if (p_reg->addr != AD7124_ERR_REG && dev->check_ready) {
+		ret = ad7124_wait_for_spi_ready(dev,
+						dev->spi_rdy_poll_cnt);
+		if (ret < 0)
+			return ret;
+	}
+	ret = ad7124_no_check_read_register(dev,
+					    p_reg);
+
+	return ret;
+}
+
+/***************************************************************************//**
+ * @brief Writes the value of the specified register only when the device is
+ *        ready to accept user requests. If the device ready flag is deactivated
+ *        the write operation will be executed without checking the device state.
+ *
+ * @param dev - The handler of the instance of the driver.
+ * @param p_reg - Register structure holding info about the register to be written
+ *
+ * @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t ad7124_write_register(struct ad7124_dev *dev,
+			      struct ad7124_st_reg p_reg)
+{
+	int32_t ret;
+
+	if (dev->check_ready) {
+		ret = ad7124_wait_for_spi_ready(dev,
+						dev->spi_rdy_poll_cnt);
+		if (ret < 0)
+			return ret;
+	}
+	ret = ad7124_no_check_write_register(dev,
+					     p_reg);
+
+	return ret;
+}
+
+/***************************************************************************//**
+ * @brief Resets the device.
+ *
+ * @param dev - The handler of the instance of the driver.
+ *
+ * @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t ad7124_reset(struct ad7124_dev *dev)
+{
+	int32_t ret = 0;
+	uint8_t wr_buf[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+	if(!dev)
+		return INVALID_VAL;
+
+	ret = spi_write_and_read(dev->spi_desc,
+				 wr_buf,
+				 8);
+
+	/* CRC is disabled after reset */
+	dev->use_crc = AD7124_DISABLE_CRC;
+
+	/* Read POR bit to clear */
+	ret = ad7124_wait_to_power_on(dev,
+				      dev->spi_rdy_poll_cnt);
+
+	mdelay(AD7124_POST_RESET_DELAY);
+
+	return ret;
+}
+
+/***************************************************************************//**
+ * @brief Waits until the device can accept read and write user actions.
+ *
+ * @param dev     - The handler of the instance of the driver.
+ * @param timeout - Count representing the number of polls to be done until the
+ *                  function returns.
+ *
+ * @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t ad7124_wait_for_spi_ready(struct ad7124_dev *dev,
+				  uint32_t timeout)
+{
+	struct ad7124_st_reg *regs;
+	int32_t ret;
+	int8_t ready = 0;
+
+	if(!dev)
+		return INVALID_VAL;
+
+	regs = dev->regs;
+
+	while(!ready && --timeout) {
+		/* Read the value of the Error Register */
+		ret = ad7124_read_register(dev, &regs[AD7124_Error]);
+		if(ret < 0)
+			return ret;
+
+		/* Check the SPI IGNORE Error bit in the Error Register */
+		ready = (regs[AD7124_Error].value &
+			 AD7124_ERR_REG_SPI_IGNORE_ERR) == 0;
+	}
+
+	return timeout ? 0 : TIMEOUT;
+}
+
+/***************************************************************************//**
+ * @brief Waits until the device finishes the power-on reset operation.
+ *
+ * @param dev     - The handler of the instance of the driver.
+ * @param timeout - Count representing the number of polls to be done until the
+ *                  function returns.
+ *
+ * @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t ad7124_wait_to_power_on(struct ad7124_dev *dev,
+				uint32_t timeout)
+{
+	struct ad7124_st_reg *regs;
+	int32_t ret;
+	int8_t powered_on = 0;
+
+	if(!dev)
+		return INVALID_VAL;
+
+	regs = dev->regs;
+
+	while(!powered_on && timeout--) {
+		ret = ad7124_read_register(dev,
+					   &regs[AD7124_Status]);
+		if(ret < 0)
+			return ret;
+
+		/* Check the POR_FLAG bit in the Status Register */
+		powered_on = (regs[AD7124_Status].value &
+			      AD7124_STATUS_REG_POR_FLAG) == 0;
+	}
+
+	return (timeout || powered_on) ? 0 : TIMEOUT;
+}
+
+/***************************************************************************//**
+ * @brief Waits until a new conversion result is available.
+ *
+ * @param dev     - The handler of the instance of the driver.
+ * @param timeout - Count representing the number of polls to be done until the
+ *                  function returns if no new data is available.
+ *
+ * @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t ad7124_wait_for_conv_ready(struct ad7124_dev *dev,
+				   uint32_t timeout)
+{
+	struct ad7124_st_reg *regs;
+	int32_t ret;
+	int8_t ready = 0;
+
+	if(!dev)
+		return INVALID_VAL;
+
+	regs = dev->regs;
+
+	while(!ready && --timeout) {
+		/* Read the value of the Status Register */
+		ret = ad7124_read_register(dev, &regs[AD7124_Status]);
+		if(ret < 0)
+			return ret;
+
+		/* Check the RDY bit in the Status Register */
+		ready = (regs[AD7124_Status].value &
+			 AD7124_STATUS_REG_RDY) == 0;
+	}
+
+	return timeout ? 0 : TIMEOUT;
+}
+
+/***************************************************************************//**
+ * @brief Reads the conversion result from the device.
+ *
+ * @param dev     - The handler of the instance of the driver.
+ * @param p_data  - Pointer to store the read data.
+ *
+ * @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t ad7124_read_data(struct ad7124_dev *dev,
+			 int32_t* p_data)
+{
+	struct ad7124_st_reg *regs;
+	int32_t ret;
+
+	if(!dev)
+		return INVALID_VAL;
+
+	regs = dev->regs;
+
+	/* Read the value of the Status Register */
+	ret = ad7124_read_register(dev, &regs[AD7124_Data]);
+
+	/* Get the read result */
+	*p_data = regs[AD7124_Data].value;
+
+	return ret;
+}
+
+/***************************************************************************//**
+ * @brief Computes the CRC checksum for a data buffer.
+ *
+ * @param p_buf    - Data buffer
+ * @param buf_size - Data buffer size in bytes
+ *
+ * @return Returns the computed CRC checksum.
+*******************************************************************************/
+uint8_t ad7124_compute_crc8(uint8_t * p_buf, uint8_t buf_size)
+{
+	uint8_t i = 0;
+	uint8_t crc = 0;
+
+	while(buf_size) {
+		for(i = 0x80; i != 0; i >>= 1) {
+			bool cmp1 = (crc & 0x80) != 0;
+			bool cmp2 = (*p_buf & i) != 0;
+			if(cmp1 != cmp2) { /* MSB of CRC register XOR input Bit from Data */
+				crc <<= 1;
+				crc ^= AD7124_CRC8_POLYNOMIAL_REPRESENTATION;
+			} else {
+				crc <<= 1;
+			}
+		}
+		p_buf++;
+		buf_size--;
+	}
+	return crc;
+}
+
+/***************************************************************************//**
+ * @brief Updates the CRC settings.
+ *
+ * @param dev - The handler of the instance of the driver.
+ *
+ * @return None.
+*******************************************************************************/
+void ad7124_update_crcsetting(struct ad7124_dev *dev)
+{
+	struct ad7124_st_reg *regs;
+
+	if(!dev)
+		return;
+
+	regs = dev->regs;
+
+	/* Get CRC State. */
+	if (regs[AD7124_Error_En].value & AD7124_ERREN_REG_SPI_CRC_ERR_EN) {
+		dev->use_crc = AD7124_USE_CRC;
+	} else {
+		dev->use_crc = AD7124_DISABLE_CRC;
+	}
+}
+
+/***************************************************************************//**
+ * @brief Updates the device SPI interface settings.
+ *
+ * @param dev - The handler of the instance of the driver.
+ *
+ * @return None.
+*******************************************************************************/
+void ad7124_update_dev_spi_settings(struct ad7124_dev *dev)
+{
+	struct ad7124_st_reg *regs;
+
+	if(!dev)
+		return;
+
+	regs = dev->regs;
+
+	if (regs[AD7124_Error_En].value & AD7124_ERREN_REG_SPI_IGNORE_ERR_EN) {
+		dev->check_ready = 1;
+	} else {
+		dev->check_ready = 0;
+	}
+}
+
+/***************************************************************************//**
+ * @brief Initializes the AD7124.
+ *
+ * @param device     - The device structure.
+ * @param init_param - The structure that contains the device initial
+ * 		       parameters.
+ *
+ * @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t ad7124_setup(struct ad7124_dev **device,
+		     struct ad7124_init_param init_param)
+{
+	int32_t ret;
+	enum ad7124_registers reg_nr;
+	struct ad7124_dev *dev;
+
+	dev = (struct ad7124_dev *)malloc(sizeof(*dev));
+	if (!dev)
+		return INVALID_VAL;
+
+	dev->regs = init_param.regs;
+	dev->spi_rdy_poll_cnt = init_param.spi_rdy_poll_cnt;
+
+	/* Initialize the SPI communication. */
+	ret = spi_init(&dev->spi_desc, &init_param.spi_init);
+	if (ret < 0)
+		return ret;
+
+	/*  Reset the device interface.*/
+	ret = ad7124_reset(dev);
+	if (ret < 0)
+		return ret;
+
+	/* Update the device structure with power-on/reset settings */
+	dev->check_ready = 1;
+
+	/* Initialize registers AD7124_ADC_Control through AD7124_Filter_7. */
+	for(reg_nr = AD7124_Status; (reg_nr < AD7124_Offset_0) && !(ret < 0);
+	    reg_nr++) {
+		if (dev->regs[reg_nr].rw == AD7124_RW) {
+			ret = ad7124_write_register(dev, dev->regs[reg_nr]);
+			if (ret < 0)
+				break;
+		}
+
+		/* Get CRC State and device SPI interface settings */
+		if (reg_nr == AD7124_Error_En) {
+			ad7124_update_crcsetting(dev);
+			ad7124_update_dev_spi_settings(dev);
+		}
+	}
+
+	*device = dev;
+
+	return ret;
+}
+
+/***************************************************************************//**
+ * @brief Free the resources allocated by AD7124_Setup().
+ *
+ * @param dev - The device structure.
+ *
+ * @return SUCCESS in case of success, negative error code otherwise.
+*******************************************************************************/
+int32_t ad7124_remove(struct ad7124_dev *dev)
+{
+	int32_t ret;
+
+	ret = spi_remove(dev->spi_desc);
+
+	free(dev);
+
+	return ret;
+}

+ 426 - 0
NoPublic/ad7124.h

@@ -0,0 +1,426 @@
+/***************************************************************************//**
+*   @file    ad7124.h
+*   @brief   AD7124 header file.
+*   	     Devices AD7124-4, AD7124-8
+*
+********************************************************************************
+* Copyright 2015-2019(c) Analog Devices, Inc.
+*
+* All rights reserved.
+*
+* 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 Analog Devices, Inc. nor the names of its
+*    contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*  - The use of this software may or may not infringe the patent rights
+*    of one or more patent holders.  This license does not release you
+*    from the requirement that you obtain separate licenses from these
+*    patent holders to use this software.
+*  - Use of the software either in source or binary form, must be run
+*    on or directly connected to an Analog Devices Inc. component.
+*
+* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY
+* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+* INTELLECTUAL PROPERTY RIGHTS, 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.
+*******************************************************************************/
+
+#ifndef __AD7124_H__
+#define __AD7124_H__
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+#include <stdint.h>
+#include "spi.h"
+#include "delay.h"
+
+/******************************************************************************/
+/******************* Register map and register definitions ********************/
+/******************************************************************************/
+
+#define	AD7124_RW 1   /* Read and Write */
+#define	AD7124_R  2   /* Read only */
+#define AD7124_W  3   /* Write only */
+
+/* AD7124 Register Map */
+#define AD7124_COMM_REG      0x00
+#define AD7124_STATUS_REG    0x00
+#define AD7124_ADC_CTRL_REG  0x01
+#define AD7124_DATA_REG      0x02
+#define AD7124_IO_CTRL1_REG  0x03
+#define AD7124_IO_CTRL2_REG  0x04
+#define AD7124_ID_REG        0x05
+#define AD7124_ERR_REG       0x06
+#define AD7124_ERREN_REG     0x07
+#define AD7124_CH0_MAP_REG   0x09
+#define AD7124_CH1_MAP_REG   0x0A
+#define AD7124_CH2_MAP_REG   0x0B
+#define AD7124_CH3_MAP_REG   0x0C
+#define AD7124_CH4_MAP_REG   0x0D
+#define AD7124_CH5_MAP_REG   0x0E
+#define AD7124_CH6_MAP_REG   0x0F
+#define AD7124_CH7_MAP_REG   0x10
+#define AD7124_CH8_MAP_REG   0x11
+#define AD7124_CH9_MAP_REG   0x12
+#define AD7124_CH10_MAP_REG  0x13
+#define AD7124_CH11_MAP_REG  0x14
+#define AD7124_CH12_MAP_REG  0x15
+#define AD7124_CH13_MAP_REG  0x16
+#define AD7124_CH14_MAP_REG  0x17
+#define AD7124_CH15_MAP_REG  0x18
+#define AD7124_CFG0_REG      0x19
+#define AD7124_CFG1_REG      0x1A
+#define AD7124_CFG2_REG      0x1B
+#define AD7124_CFG3_REG      0x1C
+#define AD7124_CFG4_REG      0x1D
+#define AD7124_CFG5_REG      0x1E
+#define AD7124_CFG6_REG      0x1F
+#define AD7124_CFG7_REG      0x20
+#define AD7124_FILT0_REG     0x21
+#define AD7124_FILT1_REG     0x22
+#define AD7124_FILT2_REG     0x23
+#define AD7124_FILT3_REG     0x24
+#define AD7124_FILT4_REG     0x25
+#define AD7124_FILT5_REG     0x26
+#define AD7124_FILT6_REG     0x27
+#define AD7124_FILT7_REG     0x28
+#define AD7124_OFFS0_REG     0x29
+#define AD7124_OFFS1_REG     0x2A
+#define AD7124_OFFS2_REG     0x2B
+#define AD7124_OFFS3_REG     0x2C
+#define AD7124_OFFS4_REG     0x2D
+#define AD7124_OFFS5_REG     0x2E
+#define AD7124_OFFS6_REG     0x2F
+#define AD7124_OFFS7_REG     0x30
+#define AD7124_GAIN0_REG     0x31
+#define AD7124_GAIN1_REG     0x32
+#define AD7124_GAIN2_REG     0x33
+#define AD7124_GAIN3_REG     0x34
+#define AD7124_GAIN4_REG     0x35
+#define AD7124_GAIN5_REG     0x36
+#define AD7124_GAIN6_REG     0x37
+#define AD7124_GAIN7_REG     0x38
+
+/* Communication Register bits */
+#define AD7124_COMM_REG_WEN    (0 << 7)
+#define AD7124_COMM_REG_WR     (0 << 6)
+#define AD7124_COMM_REG_RD     (1 << 6)
+#define AD7124_COMM_REG_RA(x)  ((x) & 0x3F)
+
+/* Status Register bits */
+#define AD7124_STATUS_REG_RDY          (1 << 7)
+#define AD7124_STATUS_REG_ERROR_FLAG   (1 << 6)
+#define AD7124_STATUS_REG_POR_FLAG     (1 << 4)
+#define AD7124_STATUS_REG_CH_ACTIVE(x) ((x) & 0xF)
+
+/* ADC_Control Register bits */
+#define AD7124_ADC_CTRL_REG_DOUT_RDY_DEL   (1 << 12)
+#define AD7124_ADC_CTRL_REG_CONT_READ      (1 << 11)
+#define AD7124_ADC_CTRL_REG_DATA_STATUS    (1 << 10)
+#define AD7124_ADC_CTRL_REG_CS_EN          (1 << 9)
+#define AD7124_ADC_CTRL_REG_REF_EN         (1 << 8)
+#define AD7124_ADC_CTRL_REG_POWER_MODE(x)  (((x) & 0x3) << 6)
+#define AD7124_ADC_CTRL_REG_MODE(x)        (((x) & 0xF) << 2)
+#define AD7124_ADC_CTRL_REG_CLK_SEL(x)     (((x) & 0x3) << 0)
+
+/* IO_Control_1 Register bits */
+#define AD7124_IO_CTRL1_REG_GPIO_DAT2     (1 << 23)
+#define AD7124_IO_CTRL1_REG_GPIO_DAT1     (1 << 22)
+#define AD7124_IO_CTRL1_REG_GPIO_CTRL2    (1 << 19)
+#define AD7124_IO_CTRL1_REG_GPIO_CTRL1    (1 << 18)
+#define AD7124_IO_CTRL1_REG_PDSW          (1 << 15)
+#define AD7124_IO_CTRL1_REG_IOUT1(x)      (((x) & 0x7) << 11)
+#define AD7124_IO_CTRL1_REG_IOUT0(x)      (((x) & 0x7) << 8)
+#define AD7124_IO_CTRL1_REG_IOUT_CH1(x)   (((x) & 0xF) << 4)
+#define AD7124_IO_CTRL1_REG_IOUT_CH0(x)   (((x) & 0xF) << 0)
+
+/* IO_Control_1 AD7124-8 specific bits */
+#define AD7124_8_IO_CTRL1_REG_GPIO_DAT4     (1 << 23)
+#define AD7124_8_IO_CTRL1_REG_GPIO_DAT3     (1 << 22)
+#define AD7124_8_IO_CTRL1_REG_GPIO_DAT2     (1 << 21)
+#define AD7124_8_IO_CTRL1_REG_GPIO_DAT1     (1 << 20)
+#define AD7124_8_IO_CTRL1_REG_GPIO_CTRL4    (1 << 19)
+#define AD7124_8_IO_CTRL1_REG_GPIO_CTRL3    (1 << 18)
+#define AD7124_8_IO_CTRL1_REG_GPIO_CTRL2    (1 << 17)
+#define AD7124_8_IO_CTRL1_REG_GPIO_CTRL1    (1 << 16)
+
+/* IO_Control_2 Register bits */
+#define AD7124_IO_CTRL2_REG_GPIO_VBIAS7   (1 << 15)
+#define AD7124_IO_CTRL2_REG_GPIO_VBIAS6   (1 << 14)
+#define AD7124_IO_CTRL2_REG_GPIO_VBIAS5   (1 << 11)
+#define AD7124_IO_CTRL2_REG_GPIO_VBIAS4   (1 << 10)
+#define AD7124_IO_CTRL2_REG_GPIO_VBIAS3   (1 << 5)
+#define AD7124_IO_CTRL2_REG_GPIO_VBIAS2   (1 << 4)
+#define AD7124_IO_CTRL2_REG_GPIO_VBIAS1   (1 << 1)
+#define AD7124_IO_CTRL2_REG_GPIO_VBIAS0   (1 << 0)
+
+/* IO_Control_2 AD7124-8 specific bits */
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS15  (1 << 15)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS14  (1 << 14)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS13  (1 << 13)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS12  (1 << 12)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS11  (1 << 11)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS10  (1 << 10)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS9   (1 << 9)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS8   (1 << 8)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS7   (1 << 7)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS6   (1 << 6)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS5   (1 << 5)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS4   (1 << 4)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS3   (1 << 3)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS2   (1 << 2)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS1   (1 << 1)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS0   (1 << 0)
+
+/* ID Register bits */
+#define AD7124_ID_REG_DEVICE_ID(x)   (((x) & 0xF) << 4)
+#define AD7124_ID_REG_SILICON_REV(x) (((x) & 0xF) << 0)
+
+/* Error Register bits */
+#define AD7124_ERR_REG_LDO_CAP_ERR        (1 << 19)
+#define AD7124_ERR_REG_ADC_CAL_ERR        (1 << 18)
+#define AD7124_ERR_REG_ADC_CONV_ERR       (1 << 17)
+#define AD7124_ERR_REG_ADC_SAT_ERR        (1 << 16)
+#define AD7124_ERR_REG_AINP_OV_ERR        (1 << 15)
+#define AD7124_ERR_REG_AINP_UV_ERR        (1 << 14)
+#define AD7124_ERR_REG_AINM_OV_ERR        (1 << 13)
+#define AD7124_ERR_REG_AINM_UV_ERR        (1 << 12)
+#define AD7124_ERR_REG_REF_DET_ERR        (1 << 11)
+#define AD7124_ERR_REG_DLDO_PSM_ERR       (1 << 9)
+#define AD7124_ERR_REG_ALDO_PSM_ERR       (1 << 7)
+#define AD7124_ERR_REG_SPI_IGNORE_ERR     (1 << 6)
+#define AD7124_ERR_REG_SPI_SLCK_CNT_ERR   (1 << 5)
+#define AD7124_ERR_REG_SPI_READ_ERR       (1 << 4)
+#define AD7124_ERR_REG_SPI_WRITE_ERR      (1 << 3)
+#define AD7124_ERR_REG_SPI_CRC_ERR        (1 << 2)
+#define AD7124_ERR_REG_MM_CRC_ERR         (1 << 1)
+#define AD7124_ERR_REG_ROM_CRC_ERR        (1 << 0)
+
+/* Error_En Register bits */
+#define AD7124_ERREN_REG_MCLK_CNT_EN           (1 << 22)
+#define AD7124_ERREN_REG_LDO_CAP_CHK_TEST_EN   (1 << 21)
+#define AD7124_ERREN_REG_LDO_CAP_CHK(x)        (((x) & 0x3) << 19)
+#define AD7124_ERREN_REG_ADC_CAL_ERR_EN        (1 << 18)
+#define AD7124_ERREN_REG_ADC_CONV_ERR_EN       (1 << 17)
+#define AD7124_ERREN_REG_ADC_SAT_ERR_EN        (1 << 16)
+#define AD7124_ERREN_REG_AINP_OV_ERR_EN        (1 << 15)
+#define AD7124_ERREN_REG_AINP_UV_ERR_EN        (1 << 14)
+#define AD7124_ERREN_REG_AINM_OV_ERR_EN        (1 << 13)
+#define AD7124_ERREN_REG_AINM_UV_ERR_EN        (1 << 12)
+#define AD7124_ERREN_REG_REF_DET_ERR_EN        (1 << 11)
+#define AD7124_ERREN_REG_DLDO_PSM_TRIP_TEST_EN (1 << 10)
+#define AD7124_ERREN_REG_DLDO_PSM_ERR_ERR      (1 << 9)
+#define AD7124_ERREN_REG_ALDO_PSM_TRIP_TEST_EN (1 << 8)
+#define AD7124_ERREN_REG_ALDO_PSM_ERR_EN       (1 << 7)
+#define AD7124_ERREN_REG_SPI_IGNORE_ERR_EN     (1 << 6)
+#define AD7124_ERREN_REG_SPI_SCLK_CNT_ERR_EN   (1 << 5)
+#define AD7124_ERREN_REG_SPI_READ_ERR_EN       (1 << 4)
+#define AD7124_ERREN_REG_SPI_WRITE_ERR_EN      (1 << 3)
+#define AD7124_ERREN_REG_SPI_CRC_ERR_EN        (1 << 2)
+#define AD7124_ERREN_REG_MM_CRC_ERR_EN         (1 << 1)
+#define AD7124_ERREN_REG_ROM_CRC_ERR_EN        (1 << 0)
+
+/* Channel Registers 0-15 bits */
+#define AD7124_CH_MAP_REG_CH_ENABLE    (1 << 15)
+#define AD7124_CH_MAP_REG_SETUP(x)     (((x) & 0x7) << 12)
+#define AD7124_CH_MAP_REG_AINP(x)      (((x) & 0x1F) << 5)
+#define AD7124_CH_MAP_REG_AINM(x)      (((x) & 0x1F) << 0)
+
+/* Configuration Registers 0-7 bits */
+#define AD7124_CFG_REG_BIPOLAR     (1 << 11)
+#define AD7124_CFG_REG_BURNOUT(x)  (((x) & 0x3) << 9)
+#define AD7124_CFG_REG_REF_BUFP    (1 << 8)
+#define AD7124_CFG_REG_REF_BUFM    (1 << 7)
+#define AD7124_CFG_REG_AIN_BUFP    (1 << 6)
+#define AD7124_CFG_REG_AINN_BUFM   (1 << 5)
+#define AD7124_CFG_REG_REF_SEL(x)  ((x) & 0x3) << 3
+#define AD7124_CFG_REG_PGA(x)      (((x) & 0x7) << 0)
+
+/* Filter Register 0-7 bits */
+#define AD7124_FILT_REG_FILTER(x)         (((x) & 0x7) << 21)
+#define AD7124_FILT_REG_REJ60             (1 << 20)
+#define AD7124_FILT_REG_POST_FILTER(x)    (((x) & 0x7) << 17)
+#define AD7124_FILT_REG_SINGLE_CYCLE      (1 << 16)
+#define AD7124_FILT_REG_FS(x)             (((x) & 0x7FF) << 0)
+
+/******************************************************************************/
+/*************************** Types Declarations *******************************/
+/******************************************************************************/
+
+/*! Device register info */
+struct ad7124_st_reg {
+	int32_t addr;
+	int32_t value;
+	int32_t size;
+	int32_t rw;
+};
+
+/*! AD7124 registers list*/
+enum ad7124_registers {
+	AD7124_Status = 0x00,
+	AD7124_ADC_Control,
+	AD7124_Data,
+	AD7124_IOCon1,
+	AD7124_IOCon2,
+	AD7124_ID,
+	AD7124_Error,
+	AD7124_Error_En,
+	AD7124_Mclk_Count,
+	AD7124_Channel_0,
+	AD7124_Channel_1,
+	AD7124_Channel_2,
+	AD7124_Channel_3,
+	AD7124_Channel_4,
+	AD7124_Channel_5,
+	AD7124_Channel_6,
+	AD7124_Channel_7,
+	AD7124_Channel_8,
+	AD7124_Channel_9,
+	AD7124_Channel_10,
+	AD7124_Channel_11,
+	AD7124_Channel_12,
+	AD7124_Channel_13,
+	AD7124_Channel_14,
+	AD7124_Channel_15,
+	AD7124_Config_0,
+	AD7124_Config_1,
+	AD7124_Config_2,
+	AD7124_Config_3,
+	AD7124_Config_4,
+	AD7124_Config_5,
+	AD7124_Config_6,
+	AD7124_Config_7,
+	AD7124_Filter_0,
+	AD7124_Filter_1,
+	AD7124_Filter_2,
+	AD7124_Filter_3,
+	AD7124_Filter_4,
+	AD7124_Filter_5,
+	AD7124_Filter_6,
+	AD7124_Filter_7,
+	AD7124_Offset_0,
+	AD7124_Offset_1,
+	AD7124_Offset_2,
+	AD7124_Offset_3,
+	AD7124_Offset_4,
+	AD7124_Offset_5,
+	AD7124_Offset_6,
+	AD7124_Offset_7,
+	AD7124_Gain_0,
+	AD7124_Gain_1,
+	AD7124_Gain_2,
+	AD7124_Gain_3,
+	AD7124_Gain_4,
+	AD7124_Gain_5,
+	AD7124_Gain_6,
+	AD7124_Gain_7,
+	AD7124_REG_NO
+};
+
+/*
+ * The structure describes the device and is used with the ad7124 driver.
+ * @spi_desc: A reference to the SPI configuration of the device.
+ * @regs: A reference to the register list of the device that the user must
+ *       provide when calling the Setup() function.
+ * @userCRC: Whether to do or not a cyclic redundancy check on SPI transfers.
+ * @check_ready: When enabled all register read and write calls will first wait
+ *               until the device is ready to accept user requests.
+ * @spi_rdy_poll_cnt: Number of times the driver should read the Error register
+ *                    to check if the device is ready to accept user requests,
+ *                    before a timeout error will be issued.
+ */
+struct ad7124_dev {
+	/* SPI */
+	spi_desc		*spi_desc;
+	/* Device Settings */
+	struct ad7124_st_reg	*regs;
+	int16_t use_crc;
+	int16_t check_ready;
+	int16_t spi_rdy_poll_cnt;
+};
+
+struct ad7124_init_param {
+	/* SPI */
+	spi_init_param		spi_init;
+	/* Device Settings */
+	struct ad7124_st_reg	*regs;
+	int16_t spi_rdy_poll_cnt;
+};
+
+/******************************************************************************/
+/******************* AD7124 Constants *****************************************/
+/******************************************************************************/
+#define AD7124_CRC8_POLYNOMIAL_REPRESENTATION 0x07 /* x8 + x2 + x + 1 */
+#define AD7124_DISABLE_CRC 0
+#define AD7124_USE_CRC 1
+
+/******************************************************************************/
+/************************ Functions Declarations ******************************/
+/******************************************************************************/
+
+/*! Reads the value of the specified register. */
+int32_t ad7124_read_register(struct ad7124_dev *dev,
+			     struct ad7124_st_reg* p_reg);
+
+/*! Writes the value of the specified register. */
+int32_t ad7124_write_register(struct ad7124_dev *dev,
+			      struct ad7124_st_reg reg);
+
+/*! Reads the value of the specified register without a device state check. */
+int32_t ad7124_no_check_read_register(struct ad7124_dev *dev,
+				      struct ad7124_st_reg* p_reg);
+
+/*! Writes the value of the specified register without a device state check. */
+int32_t ad7124_no_check_write_register(struct ad7124_dev *dev,
+				       struct ad7124_st_reg reg);
+
+/*! Resets the device. */
+int32_t ad7124_reset(struct ad7124_dev *dev);
+
+/*! Waits until the device can accept read and write user actions. */
+int32_t ad7124_wait_for_spi_ready(struct ad7124_dev *dev,
+				  uint32_t timeout);
+
+/*! Waits until the device finishes the power-on reset operation. */
+int32_t ad7124_wait_to_power_on(struct ad7124_dev *dev,
+				uint32_t timeout);
+
+/*! Waits until a new conversion result is available. */
+int32_t ad7124_wait_for_conv_ready(struct ad7124_dev *dev,
+				   uint32_t timeout);
+
+/*! Reads the conversion result from the device. */
+int32_t ad7124_read_data(struct ad7124_dev *dev,
+			 int32_t* p_data);
+
+/*! Computes the CRC checksum for a data buffer. */
+uint8_t ad7124_compute_crc8(uint8_t* p_buf,
+			    uint8_t buf_size);
+
+/*! Updates the CRC settings. */
+void ad7124_update_crcsetting(struct ad7124_dev *dev);
+
+/*! Updates the device SPI interface settings. */
+void ad7124_update_dev_spi_settings(struct ad7124_dev *dev);
+
+/*! Initializes the AD7124. */
+int32_t ad7124_setup(struct ad7124_dev **device,
+		     struct ad7124_init_param init_param);
+/*! Free the resources allocated by AD7124_Setup(). */
+int32_t ad7124_remove(struct ad7124_dev *dev);
+
+#endif /* __AD7124_H__ */

+ 637 - 0
NoPublic/ad7124_console_app.c

@@ -0,0 +1,637 @@
+/*!
+ *****************************************************************************
+  @file:  ad7124_console_app.c
+
+  @brief: Implementation for the menu functions that handle the AD7124
+
+  @details:
+ -----------------------------------------------------------------------------
+Copyright (c) 2019 Analog Devices, Inc.  All rights reserved.
+
+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.
+  - Modified versions of the software must be conspicuously marked as such.
+  - This software is licensed solely and exclusively for use with processors/
+    products manufactured by or for Analog Devices, Inc.
+  - This software may not be combined or merged with other code in any manner
+    that would cause the software to become subject to terms and conditions
+	which differ from those listed here.
+  - Neither the name of Analog Devices, Inc. nor the names of its contributors
+    may be used to endorse or promote products derived from this software without
+    specific prior written permission.
+  - The use of this software may or may not infringe the patent rights of one
+    or more patent holders.  This license does not release you from the
+	requirement that you obtain separate licenses from these patent holders
+	to use this software.
+
+THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-
+INFRINGEMENT, TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF
+CLAIMS OF INTELLECTUAL PROPERTY RIGHTS INFRINGEMENT; 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.
+
+20180927-7CBSD SLA
+
+*****************************************************************************/
+
+/* includes */
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "platform_support.h"
+#include "spi.h"
+#include "error.h"
+
+#include "ad7124.h"
+#include "ad7124_regs.h"
+#include "ad7124_support.h"
+#include "ad7124_regs_configs.h"
+
+#include "ad7124_console_app.h"
+
+
+/*  defines */
+#define AD7124_CHANNEL_COUNT 16
+
+#define SHOW_ALL_CHANNELS     false
+#define SHOW_ENABLED_CHANNELS  true
+
+#define DISPLAY_DATA_TABULAR    0
+#define DISPLAY_DATA_STREAM     1
+
+/* Private Variables */
+/*
+ * This is the 'live' AD7124 register map that is used by the driver
+ * the other 'default' configs are used to populate this at init time
+ */
+static struct ad7124_st_reg ad7124_register_map[AD7124_REG_NO];
+
+// Pointer to the struct representing the AD7124 device
+static struct ad7124_dev * pAd7124_dev = NULL;
+
+// Last Sampled values for All ADC channels
+static uint32_t channel_samples[AD7124_CHANNEL_COUNT] = {0};
+// How many times a given channel is sampled in total for one sample run
+static uint32_t channel_samples_count[AD7124_CHANNEL_COUNT] = {0};
+
+
+// Public Functions
+
+/*!
+ * @brief      Initialize the AD7124 device and the SPI port as required
+ *
+ * @details    This resets and then writes the default register map value to
+ *  		   the device.  A call to init the SPI port is made, but may not
+ *  		   actually do very much, depending on the platform
+ */
+int32_t ad7124_app_initialize(uint8_t configID)
+{
+	/*
+	 * Copy one of the default/user configs to the live register memory map
+	 * Requirement, not checked here, is that all the configs are the same size
+	 */
+	switch(configID) {
+		case AD7124_CONFIG_A:
+		{
+			memcpy(ad7124_register_map, ad7124_regs_config_a, sizeof(ad7124_register_map));
+			break;
+		}
+		case AD7124_CONFIG_B:
+		{
+			memcpy(ad7124_register_map, ad7124_regs_config_b, sizeof(ad7124_register_map));
+			break;
+		}
+		default:
+			// Not a defined configID
+			return(FAILURE);
+	}
+
+	// Used to create the ad7124 device
+    struct	ad7124_init_param sAd7124_init =
+  	{
+  		// spi_init_param type
+  		{
+  			2500000, 		// Max SPI Speed
+  			0,				// Chip Select
+			SPI_MODE_3,		// CPOL = 1, CPHA =1
+			NULL
+  		},
+  		ad7124_register_map,
+
+  		10000				// Retry count for polling
+  	};
+
+  return(ad7124_setup(&pAd7124_dev, sAd7124_init));
+}
+
+// Private Functions
+
+/*!
+ * @brief      determines if the Escape key was pressed
+ *
+ * @details
+ */
+static bool was_escape_key_pressed(void)
+{
+	char rxChar;
+	bool wasPressed = false;
+
+	// Check for Escape key pressed
+	if ((rxChar = getchar_nonblocking()) > 0) {
+		if (rxChar == ESCAPE_KEY_CODE) {
+			wasPressed = true;
+		}
+	}
+	return (wasPressed);
+}
+
+
+/*!
+ * @brief      reads and displays the status register on the AD7124
+ *
+ * @details
+ */
+static void read_status_register(void)
+{
+	if (ad7124_read_register(pAd7124_dev, &ad7124_register_map[AD7124_Status]) < 0) {
+	   printf("\r\nError Encountered reading Status register\r\n");
+	} else {
+	    uint32_t status_value = (uint32_t)ad7124_register_map[AD7124_Status].value;
+        printf("\r\nRead Status Register = 0x%02lx\r\n", status_value);
+	}
+}
+
+
+/*!
+ * @brief      displays the current sample value for a ADC channels
+ *
+ * @details
+ *
+ * @param showOnlyEnabledChannels  only channels that are enabled are displayed
+ *
+ */
+static void dislay_channel_samples(bool showOnlyEnabledChannels, uint8_t console_mode)
+{
+	switch(console_mode) {
+		case DISPLAY_DATA_TABULAR:
+		{
+			printf("\tCh\tValue\t\tCount\t\tVoltage\r\n");
+			for (uint8_t i = 0; i < AD7124_CHANNEL_COUNT; i++) {
+				// if showing all channels, or channel is enabled
+				if ((showOnlyEnabledChannels == false) || (ad7124_register_map[AD7124_Channel_0 + i].value & AD7124_CH_MAP_REG_CH_ENABLE) ) {
+				   printf("\t%-2d\t%-10ld\t%ld\t\t% .6f\r\n", \
+							i, channel_samples[i], channel_samples_count[i],
+							ad7124_convert_sample_to_voltage(pAd7124_dev, i, channel_samples[i]) );
+				}
+			}
+			break;
+		}
+		case DISPLAY_DATA_STREAM:
+		{
+			// Output a CSV list of the sampled channels as voltages on a single line
+			bool channel_printed = false;
+
+			for (uint8_t i = 0; i < AD7124_CHANNEL_COUNT; i++) {
+				// if showing all channels, or channel is enabled
+				if ((showOnlyEnabledChannels == false) || (ad7124_register_map[AD7124_Channel_0 + i].value & AD7124_CH_MAP_REG_CH_ENABLE) ) {
+					/*
+					 *  add the comma before we output the next channel but
+					 *  only if at least one channel has been printed
+					 */
+				   if (channel_printed) {
+					   printf(", ");
+				   }
+					printf("%.6f", \
+							ad7124_convert_sample_to_voltage(pAd7124_dev, i, channel_samples[i]) );
+					channel_printed = true;
+				}
+			}
+			printf("\r\n");
+			break;
+		}
+		default:
+		{
+			// ASSERT(false);
+		}
+	}
+}
+
+
+/*!
+ * @brief      resets the channelSampleCounts to zero
+ *
+ * @details
+ */
+static void clear_channel_samples(void)
+{
+    for (uint8_t i = 0; i < AD7124_CHANNEL_COUNT; i++) {
+    	channel_samples[i] = 0;
+    	channel_samples_count[i] = 0;
+    }
+}
+
+
+/*!
+ * @brief      Continuously acquires samples in Continuous Conversion mode
+ *
+ * @details   The ADC is run in continuous mode, and all samples are acquired
+ *            and assigned to the channel they come from. Escape key an be used
+ *            to exit the loop
+ */
+static int32_t do_continuous_conversion(uint8_t display_mode)
+{
+	int32_t error_code;
+	int32_t sample_data;
+
+	// Clear the ADC CTRL MODE bits, has the effect of selecting continuous mode
+    ad7124_register_map[AD7124_ADC_Control].value &= ~(AD7124_ADC_CTRL_REG_MODE(0xf));
+	if ( (error_code = ad7124_write_register(pAd7124_dev, ad7124_register_map[AD7124_ADC_Control]) ) < 0) {
+		printf("Error (%ld) setting AD7124 Continuous conversion mode.\r\n", error_code);
+		adi_press_any_key_to_continue();
+		return(MENU_CONTINUE);
+	}
+
+	clear_channel_samples();
+
+	/*
+	 *  If displaying data in stream form, want to output a channel header
+	 */
+	if (display_mode == DISPLAY_DATA_STREAM)
+	{
+		bool channel_printed = false;
+
+		for (uint8_t i = 0; i < AD7124_CHANNEL_COUNT; i++) {
+		   // if showing all channels, or channel is enabled
+			if (ad7124_register_map[AD7124_Channel_0 + i].value & AD7124_CH_MAP_REG_CH_ENABLE) {
+				/*
+				 *  add the comma before we output the next channel but
+				 *  only if at least one channel has been printed
+				 */
+			   if (channel_printed) {
+				   printf(", ");
+			   }
+				printf("%d", i);
+			}
+			channel_printed = true;
+		}
+		printf("\r\n");
+	}
+
+	// Continuously read the channels, and store sample values
+    while (was_escape_key_pressed() != true) {
+    	toggle_activity_led();
+
+    	if (display_mode == DISPLAY_DATA_TABULAR) {
+    		adi_clear_console();
+    		printf("Running continuous conversion mode...\r\nPress Escape to stop\r\n\r\n");
+    	}
+
+		/*
+		 *  this polls the status register READY/ bit to determine when conversion is done
+		 *  this also ensures the STATUS register value is up to date and contains the
+		 *  channel that was sampled as well.
+		 *  Generally, no need to read STATUS separately, but for faster sampling
+		 *  enabling the DATA_STATUS bit means that status is appended to ADC data read
+		 *  so the channel being sampled is read back (and updated) as part of the same frame
+		 */
+
+    	if ( (error_code = ad7124_wait_for_conv_ready(pAd7124_dev, 10000)) < 0) {
+    		printf("Error/Timeout waiting for conversion ready %ld\r\n", error_code);
+    		continue;
+    	}
+
+    	if ( (error_code = ad7124_read_data(pAd7124_dev, &sample_data)) < 0) {
+			printf("Error reading ADC Data (%ld).\r\n", error_code);
+			continue;
+		}
+
+		/*
+		 * No error, need to process the sample, what channel has been read? update that channelSample
+		 */
+		uint8_t channel_read = ad7124_register_map[AD7124_Status].value & 0x0000000F;
+
+		if (channel_read < AD7124_CHANNEL_COUNT) {
+			channel_samples[channel_read] = sample_data;
+			channel_samples_count[channel_read]++;
+		} else {
+			printf("Channel Read was %d, which is not < AD7124_CHANNEL_COUNT\r\n", channel_read);
+		}
+
+		dislay_channel_samples(SHOW_ENABLED_CHANNELS, display_mode);
+    }
+
+    // All done, ADC put into standby mode
+    ad7124_register_map[AD7124_ADC_Control].value &= ~(AD7124_ADC_CTRL_REG_MODE(0xf));
+    // 2 = sleep/standby mode
+    ad7124_register_map[AD7124_ADC_Control].value |= AD7124_ADC_CTRL_REG_MODE(2);
+
+	if ( (error_code = ad7124_write_register(pAd7124_dev, ad7124_register_map[AD7124_ADC_Control]) ) < 0) {
+		printf("Error (%ld) setting AD7124 ADC into standby mode.\r\n", error_code);
+		adi_press_any_key_to_continue();
+	}
+
+	return(MENU_CONTINUE);
+}
+
+
+/*!
+ * @brief      Samples all enabled channels and displays in tabular form
+ *
+ * @details
+ */
+static int32_t menu_continuous_conversion_tabular(void)
+{
+	do_continuous_conversion(DISPLAY_DATA_TABULAR);
+
+	adi_clear_console();
+	printf("Continuous Conversion completed...\r\n\r\n");
+	dislay_channel_samples(SHOW_ALL_CHANNELS, DISPLAY_DATA_TABULAR);
+	adi_press_any_key_to_continue();
+
+	return(MENU_CONTINUE);
+}
+
+
+/*!
+ * @brief      Samples all enabled channels and displays on the console
+ *
+ * @details
+ */
+static int32_t menu_continuous_conversion_stream(void)
+{
+	do_continuous_conversion(DISPLAY_DATA_STREAM);
+	printf("Continuous Conversion completed...\r\n\r\n");
+	adi_press_any_key_to_continue();
+	return(MENU_CONTINUE);
+}
+
+
+/*!
+ * @brief      Samples all enabled channels once in Single Conversion mode
+ *
+ * @details    This stores all channels that are enabled in a bitmask, and then
+ *             runs the ADC in single conversion mode, which acquires one channel
+ *             of data at a time. After capture, that channel is disabled, and
+ *             single conversion run again, until no channels are enabled.
+ *             The original enable state of each channel is then restored.
+ */
+static int32_t menu_single_conversion(void)
+{
+	int32_t    error_code;
+	uint16_t   channel_enable_mask = 0;
+	uint8_t    channel_count = 0;
+	int32_t    sample_data;
+
+	// Need to store which channels are enabled in this config so it can be restored
+	for (uint8_t i = 0; i < AD7124_CHANNEL_COUNT; i++) {
+		if (ad7124_register_map[AD7124_Channel_0 + i].value & AD7124_CH_MAP_REG_CH_ENABLE) {
+			channel_enable_mask |= (1 << i);
+			channel_count++;
+		}
+	}
+
+	clear_channel_samples();
+	adi_clear_console();
+	printf("Running Single conversion mode...\r\nPress Escape to stop\r\n\r\n");
+
+	// Clear the ADC CTRL MODE bits, selecting continuous mode
+    ad7124_register_map[AD7124_ADC_Control].value &= ~(AD7124_ADC_CTRL_REG_MODE(0xf));
+
+	// read the channels, and store sample values
+    for (uint8_t loopCount = 0; ((was_escape_key_pressed()!= true ) && (loopCount < channel_count)) ; loopCount++) {
+    	toggle_activity_led();
+
+    	// 1 = single conversion mode
+        ad7124_register_map[AD7124_ADC_Control].value |= AD7124_ADC_CTRL_REG_MODE(1);
+
+    	if ( (error_code = ad7124_write_register(pAd7124_dev, ad7124_register_map[AD7124_ADC_Control]) ) < 0) {
+    		printf("Error (%ld) setting AD7124 Single conversion mode.\r\n", error_code);
+    		adi_press_any_key_to_continue();
+    		continue;
+    	}
+
+        /*
+         *  this polls the status register READY/ bit to determine when conversion is done
+         *  this also ensures the STATUS register value is up to date and contains the
+         *  channel that was sampled as well. No need to read STATUS separately
+         */
+    	if ( (error_code = ad7124_wait_for_conv_ready(pAd7124_dev, 10000)) < 0) {
+    		printf("Error/Timeout waiting for conversion ready %ld\r\n", error_code);
+    		continue;
+    	}
+
+    	if ( (error_code = ad7124_read_data(pAd7124_dev, &sample_data)) < 0) {
+			printf("Error reading ADC Data (%ld).\r\n", error_code);
+			continue;
+		}
+    	/*
+		 * No error, need to process the sample, what channel has been read? update that channelSample
+		 */
+		uint8_t channelRead = ad7124_register_map[AD7124_Status].value & 0x0000000F;
+
+		if (channelRead < AD7124_CHANNEL_COUNT) {
+			channel_samples[channelRead] = sample_data;
+			channel_samples_count[channelRead]++;
+
+			/* also need to clear the channel enable bit so the next single conversion cycle will sample the next channel */
+			ad7124_register_map[AD7124_Channel_0 + channelRead].value &= ~AD7124_CH_MAP_REG_CH_ENABLE;
+			if ( (error_code = ad7124_write_register(pAd7124_dev, ad7124_register_map[AD7124_Channel_0 + channelRead]) ) < 0) {
+				printf("Error (%ld) Clearing channel %d Enable bit.\r\n", error_code, channelRead);
+				adi_press_any_key_to_continue();
+				continue;
+			}
+		} else {
+			printf("Channel Read was %d, which is not < AD7124_CHANNEL_COUNT\r\n", channelRead);
+		}
+    }
+
+    // All done, ADC put into standby mode
+    ad7124_register_map[AD7124_ADC_Control].value &= ~(AD7124_ADC_CTRL_REG_MODE(0xf));
+    // 2 = sleep/standby mode
+    ad7124_register_map[AD7124_ADC_Control].value |= AD7124_ADC_CTRL_REG_MODE(2);
+
+	// Need to restore the channels that were disabled during acquisition
+	for (uint8_t i = 0; i < AD7124_CHANNEL_COUNT; i++) {
+		if (channel_enable_mask & (1 << i)) {
+			ad7124_register_map[AD7124_Channel_0 + i].value |= AD7124_CH_MAP_REG_CH_ENABLE;
+	    	if ( (error_code = ad7124_write_register(pAd7124_dev, ad7124_register_map[AD7124_Channel_0 + i]) ) < 0) {
+	    		printf("Error (%ld) Setting channel %d Enable bit.\r\r\n", error_code, i);
+	    		adi_press_any_key_to_continue();
+	    		return(MENU_CONTINUE);
+	    	}
+		}
+	}
+
+	printf("Single Conversion completed...\r\n\r\n");
+	dislay_channel_samples(SHOW_ENABLED_CHANNELS, DISPLAY_DATA_TABULAR);
+
+	adi_press_any_key_to_continue();
+	return(MENU_CONTINUE);
+}
+
+
+/*!
+ * @brief      menu item that reads the status register the AD7124
+ *
+ * @details
+ */
+static int32_t menu_read_status(void)
+{
+	read_status_register();
+	adi_press_any_key_to_continue();
+	return(MENU_CONTINUE);
+}
+
+
+/*!
+ * @brief      reads the ID register on the AD7124
+ *
+ * @details
+ */
+static int32_t menu_read_id(void)
+{
+	if (ad7124_read_register(pAd7124_dev, &ad7124_register_map[AD7124_ID]) < 0) {
+	   printf("\r\nError Encountered reading ID register\r\n");
+	} else {
+	   printf("\r\nRead ID Register = 0x%02lx\r\n",
+			   (uint32_t)ad7124_register_map[AD7124_ID].value );
+	}
+	adi_press_any_key_to_continue();
+	return(MENU_CONTINUE);
+}
+
+
+/*!
+ * @brief      Initialize the part with a specific configuration
+ *
+ * @details
+ */
+static void init_with_configuration(uint8_t configID)
+{
+	int32_t status = 0;
+
+	do {
+		if ((status = ad7124_remove(pAd7124_dev)) < 0) {
+			break;
+		}
+
+		if ((status = ad7124_app_initialize(configID)) < 0) {
+			break;
+		}
+	} while(0);
+
+	if (status < 0) {
+		printf("\r\n\r\n Error setting Configuration %c \r\n\r\n", (char)(configID + 'A'));
+	} else {
+		printf("\r\n\r\n Configuration %c Set\r\n\r\n", (char)(configID + 'A'));
+	}
+	adi_press_any_key_to_continue();
+}
+
+
+/*
+ * @brief      Sends a reset command on the SPI to reset the AD7124
+ *
+ * @details
+ */
+static int32_t menu_reset(void)
+{
+	if (ad7124_reset(pAd7124_dev)  < 0)
+	{
+		printf("\r\n\r\n Error performing Reset\r\n\r\n");
+	} else
+	{
+		// Need to set the live register map to defaults as well
+		memcpy(ad7124_register_map, ad7124_regs, sizeof(ad7124_register_map));
+		printf("\r\n\r\n Reset Complete\r\n\r\n");
+	}
+	adi_press_any_key_to_continue();
+	return(MENU_CONTINUE);
+}
+
+
+/*!
+ * @brief      Reset and set the ad7124 with configuration A
+ *
+ * @details
+ */
+static int32_t menu_reset_to_configuration_a(void)
+{
+	init_with_configuration(AD7124_CONFIG_A);
+	return(MENU_CONTINUE);
+}
+
+
+/*!
+ * @brief      Reset and the ad7124 with configuration B
+ *
+ * @details
+ */
+static int32_t menu_reset_to_configuration_b(void)
+{
+	init_with_configuration(AD7124_CONFIG_B);
+	return(MENU_CONTINUE);
+}
+
+
+/*
+ * Definition of the Sampling Menu Items and menu itself
+ */
+static console_menu_item acquisition_menu_items[] = {
+		{"Single Conversion Mode",	                 	'S', menu_single_conversion},
+	    {"Continuous Conversion Mode - Table View",	    'T', menu_continuous_conversion_tabular},
+		{"Continuous Conversion Mode - Stream Data",	'C', menu_continuous_conversion_stream},
+};
+
+static console_menu acquisition_menu = {
+    "Data Acquisition Menu",
+	acquisition_menu_items,
+	ARRAY_SIZE(acquisition_menu_items),
+	true
+};
+
+
+/*!
+ * @brief      displays and handles the Sample Channel menu
+ *
+ * @details
+ */
+static int32_t menu_sample_channels(void)
+{
+	return(adi_do_console_menu(&acquisition_menu));
+}
+
+
+/*
+ * Definition of the Main Menu Items and menu itself
+ */
+console_menu_item main_menu_items[] = {
+	{"Reset to Default Configuration",	'R', menu_reset},
+	{"Reset to Configuration A",		'A', menu_reset_to_configuration_a},
+    {"Reset to Configuration B",		'B', menu_reset_to_configuration_b},
+	{"", 								'\00', NULL},
+	{"Read ID Register",				'I', menu_read_id},
+	{"Read Status Register",			'T', menu_read_status},
+	{"", 								'\00', NULL},
+    {"Sample Channels...",				'S', menu_sample_channels},
+};
+
+console_menu ad7124_main_menu = {
+    "AD7124 Main Menu",
+    main_menu_items,
+	ARRAY_SIZE(main_menu_items),
+	false
+};

+ 64 - 0
NoPublic/ad7124_console_app.h

@@ -0,0 +1,64 @@
+/*!
+ *****************************************************************************
+  @file:  ad7124_console_app.h
+
+  @brief: defines the console menu structure for the AD7124 example code
+
+  @details:
+ -----------------------------------------------------------------------------
+Copyright (c) 2019 Analog Devices, Inc.  All rights reserved.
+
+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.
+  - Modified versions of the software must be conspicuously marked as such.
+  - This software is licensed solely and exclusively for use with processors/
+    products manufactured by or for Analog Devices, Inc.
+  - This software may not be combined or merged with other code in any manner
+    that would cause the software to become subject to terms and conditions
+	which differ from those listed here.
+  - Neither the name of Analog Devices, Inc. nor the names of its contributors
+    may be used to endorse or promote products derived from this software without
+    specific prior written permission.
+  - The use of this software may or may not infringe the patent rights of one
+    or more patent holders.  This license does not release you from the
+	requirement that you obtain separate licenses from these patent holders
+	to use this software.
+
+THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-
+INFRINGEMENT, TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF
+CLAIMS OF INTELLECTUAL PROPERTY RIGHTS INFRINGEMENT; 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.
+
+20180927-7CBSD SLA
+
+*****************************************************************************/
+
+#ifndef AD7124_CONSOLE_APP_H_
+#define AD7124_CONSOLE_APP_H_
+
+#include "adi_console_menu.h"
+
+/* #defines */
+#define AD7124_CONFIG_A       0
+#define AD7124_CONFIG_B       1
+
+/* Public Declarations */
+int32_t ad7124_app_initialize(uint8_t configID);
+
+extern console_menu ad7124_main_menu;
+
+
+#endif /* AD7124_CONSOLE_APP_H_ */

+ 102 - 0
NoPublic/ad7124_regs.c

@@ -0,0 +1,102 @@
+/***************************************************************************//**
+*   @file    ad7124_regs.c
+*   @brief   AD7124 register file.
+*   	     Devices: AD7124-4, AD7124-8
+*
+********************************************************************************
+* Copyright 2015-2019(c) Analog Devices, Inc.
+*
+* All rights reserved.
+*
+* 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 Analog Devices, Inc. nor the names of its
+*    contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*  - The use of this software may or may not infringe the patent rights
+*    of one or more patent holders.  This license does not release you
+*    from the requirement that you obtain separate licenses from these
+*    patent holders to use this software.
+*  - Use of the software either in source or binary form, must be run
+*    on or directly connected to an Analog Devices Inc. component.
+*
+* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY
+* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+* INTELLECTUAL PROPERTY RIGHTS, 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 "ad7124_regs.h"
+
+struct ad7124_st_reg ad7124_regs[AD7124_REG_NO] = {
+	{0x00, 0x00,   1, 2}, /* AD7124_Status */
+	{0x01, 0x0000, 2, 1}, /* AD7124_ADC_Control */
+	{0x02, 0x0000, 3, 2}, /* AD7124_Data */
+	{0x03, 0x0000, 3, 1}, /* AD7124_IOCon1 */
+	{0x04, 0x0000, 2, 1}, /* AD7124_IOCon2 */
+	{0x05, 0x02,   1, 2}, /* AD7124_ID */
+	{0x06, 0x0000, 3, 2}, /* AD7124_Error */
+	{0x07, 0x0040, 3, 1}, /* AD7124_Error_En */
+	{0x08, 0x00,   1, 2}, /* AD7124_Mclk_Count */
+	{0x09, 0x8001, 2, 1}, /* AD7124_Channel_0 */
+	{0x0A, 0x0001, 2, 1}, /* AD7124_Channel_1 */
+	{0x0B, 0x0001, 2, 1}, /* AD7124_Channel_2 */
+	{0x0C, 0x0001, 2, 1}, /* AD7124_Channel_3 */
+	{0x0D, 0x0001, 2, 1}, /* AD7124_Channel_4 */
+	{0x0E, 0x0001, 2, 1}, /* AD7124_Channel_5 */
+	{0x0F, 0x0001, 2, 1}, /* AD7124_Channel_6 */
+	{0x10, 0x0001, 2, 1}, /* AD7124_Channel_7 */
+	{0x11, 0x0001, 2, 1}, /* AD7124_Channel_8 */
+	{0x12, 0x0001, 2, 1}, /* AD7124_Channel_9 */
+	{0x13, 0x0001, 2, 1}, /* AD7124_Channel_10 */
+	{0x14, 0x0001, 2, 1}, /* AD7124_Channel_11 */
+	{0x15, 0x0001, 2, 1}, /* AD7124_Channel_12 */
+	{0x16, 0x0001, 2, 1}, /* AD7124_Channel_13 */
+	{0x17, 0x0001, 2, 1}, /* AD7124_Channel_14 */
+	{0x18, 0x0001, 2, 1}, /* AD7124_Channel_15 */
+	{0x19, 0x0860, 2, 1}, /* AD7124_Config_0 */
+	{0x1A, 0x0860, 2, 1}, /* AD7124_Config_1 */
+	{0x1B, 0x0860, 2, 1}, /* AD7124_Config_2 */
+	{0x1C, 0x0860, 2, 1}, /* AD7124_Config_3 */
+	{0x1D, 0x0860, 2, 1}, /* AD7124_Config_4 */
+	{0x1E, 0x0860, 2, 1}, /* AD7124_Config_5 */
+	{0x1F, 0x0860, 2, 1}, /* AD7124_Config_6 */
+	{0x20, 0x0860, 2, 1}, /* AD7124_Config_7 */
+	{0x21, 0x060180, 3, 1}, /* AD7124_Filter_0 */
+	{0x22, 0x060180, 3, 1}, /* AD7124_Filter_1 */
+	{0x23, 0x060180, 3, 1}, /* AD7124_Filter_2 */
+	{0x24, 0x060180, 3, 1}, /* AD7124_Filter_3 */
+	{0x25, 0x060180, 3, 1}, /* AD7124_Filter_4 */
+	{0x26, 0x060180, 3, 1}, /* AD7124_Filter_5 */
+	{0x27, 0x060180, 3, 1}, /* AD7124_Filter_6 */
+	{0x28, 0x060180, 3, 1}, /* AD7124_Filter_7 */
+	{0x29, 0x800000, 3, 1}, /* AD7124_Offset_0 */
+	{0x2A, 0x800000, 3, 1}, /* AD7124_Offset_1 */
+	{0x2B, 0x800000, 3, 1}, /* AD7124_Offset_2 */
+	{0x2C, 0x800000, 3, 1}, /* AD7124_Offset_3 */
+	{0x2D, 0x800000, 3, 1}, /* AD7124_Offset_4 */
+	{0x2E, 0x800000, 3, 1}, /* AD7124_Offset_5 */
+	{0x2F, 0x800000, 3, 1}, /* AD7124_Offset_6 */
+	{0x30, 0x800000, 3, 1}, /* AD7124_Offset_7 */
+	{0x31, 0x500000, 3, 1}, /* AD7124_Gain_0 */
+	{0x32, 0x500000, 3, 1}, /* AD7124_Gain_1 */
+	{0x33, 0x500000, 3, 1}, /* AD7124_Gain_2 */
+	{0x34, 0x500000, 3, 1}, /* AD7124_Gain_3 */
+	{0x35, 0x500000, 3, 1}, /* AD7124_Gain_4 */
+	{0x36, 0x500000, 3, 1}, /* AD7124_Gain_5 */
+	{0x37, 0x500000, 3, 1}, /* AD7124_Gain_6 */
+	{0x38, 0x500000, 3, 1}, /* AD7124_Gain_7 */
+};

+ 51 - 0
NoPublic/ad7124_regs.h

@@ -0,0 +1,51 @@
+/***************************************************************************//**
+*   @file    ad7124_regs.h
+*   @brief   AD7124 register file.
+*            Devices: AD7124-4, AD7124-8
+*
+********************************************************************************
+* Copyright 2015-2019(c) Analog Devices, Inc.
+*
+* All rights reserved.
+*
+* 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 Analog Devices, Inc. nor the names of its
+*    contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*  - The use of this software may or may not infringe the patent rights
+*    of one or more patent holders.  This license does not release you
+*    from the requirement that you obtain separate licenses from these
+*    patent holders to use this software.
+*  - Use of the software either in source or binary form, must be run
+*    on or directly connected to an Analog Devices Inc. component.
+*
+* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY
+* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+* INTELLECTUAL PROPERTY RIGHTS, 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.
+*******************************************************************************/
+
+
+#ifndef __AD7124_REGS_H__
+#define __AD7124_REGS_H__
+
+#include "ad7124.h"
+
+/*! Array holding the info for the ad7124 registers - address, initial value,
+    size and access type. */
+extern struct ad7124_st_reg ad7124_regs[AD7124_REG_NO];
+
+#endif /* __AD7124_REGS_H__ */

+ 111 - 0
NoPublic/ad7124_regs_config_a.c

@@ -0,0 +1,111 @@
+/*!
+ *****************************************************************************
+  @file:  ad7124_regs_config_a.c
+
+  @brief: Configuration file A for AD7124
+
+  @details:
+ -----------------------------------------------------------------------------
+Copyright (c) 2019 Analog Devices, Inc.
+
+All rights reserved.
+
+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.
+  - Modified versions of the software must be conspicuously marked as such.
+  - This software is licensed solely and exclusively for use with processors/
+    products manufactured by or for Analog Devices, Inc.
+  - This software may not be combined or merged with other code in any manner
+    that would cause the software to become subject to terms and conditions
+	which differ from those listed here.
+  - Neither the name of Analog Devices, Inc. nor the names of its contributors
+    may be used to endorse or promote products derived from this software without
+    specific prior written permission.
+  - The use of this software may or may not infringe the patent rights of one
+    or more patent holders.  This license does not release you from the
+	requirement that you obtain separate licenses from these patent holders
+	to use this software.
+
+THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-
+INFRINGEMENT, TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF
+CLAIMS OF INTELLECTUAL PROPERTY RIGHTS INFRINGEMENT; 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.
+
+20180927-7CBSD SLA
+
+*****************************************************************************/
+
+#include "ad7124_regs.h"
+
+const struct ad7124_st_reg ad7124_regs_config_a[AD7124_REG_NO] = {
+{0x00, 0x00, 1, 2},
+{0x01, 0x0708, 2, 1},
+{0x02, 0x000000, 3, 2},
+{0x03, 0x000000, 3, 1},
+{0x04, 0x0000, 2, 1},
+{0x05, 0x00, 1, 2},
+{0x06, 0x000000, 3, 2},
+{0x07, 0x000044, 3, 1},
+{0x08, 0x00, 1, 2},
+{0x09, 0x8001, 2, 1},
+{0x0A, 0x0001, 2, 1},
+{0x0B, 0x0001, 2, 1},
+{0x0C, 0x0001, 2, 1},
+{0x0D, 0x0001, 2, 1},
+{0x0E, 0x0001, 2, 1},
+{0x0F, 0x0001, 2, 1},
+{0x10, 0x0001, 2, 1},
+{0x11, 0x0001, 2, 1},
+{0x12, 0x0001, 2, 1},
+{0x13, 0x0001, 2, 1},
+{0x14, 0x0001, 2, 1},
+{0x15, 0x0001, 2, 1},
+{0x16, 0x0001, 2, 1},
+{0x17, 0x0001, 2, 1},
+{0x18, 0x0001, 2, 1},
+{0x19, 0x0860, 2, 1},
+{0x1A, 0x0860, 2, 1},
+{0x1B, 0x0860, 2, 1},
+{0x1C, 0x0860, 2, 1},
+{0x1D, 0x0860, 2, 1},
+{0x1E, 0x0860, 2, 1},
+{0x1F, 0x0860, 2, 1},
+{0x20, 0x0860, 2, 1},
+{0x21, 0x060014, 3, 1},
+{0x22, 0x060180, 3, 1},
+{0x23, 0x060180, 3, 1},
+{0x24, 0x060180, 3, 1},
+{0x25, 0x060180, 3, 1},
+{0x26, 0x060180, 3, 1},
+{0x27, 0x060180, 3, 1},
+{0x28, 0x060180, 3, 1},
+{0x29, 0x800000, 3, 1},
+{0x2A, 0x800000, 3, 1},
+{0x2B, 0x800000, 3, 1},
+{0x2C, 0x800000, 3, 1},
+{0x2D, 0x800000, 3, 1},
+{0x2E, 0x800000, 3, 1},
+{0x2F, 0x800000, 3, 1},
+{0x30, 0x800000, 3, 1},
+{0x31, 0x500000, 3, 1},
+{0x32, 0x500000, 3, 1},
+{0x33, 0x500000, 3, 1},
+{0x34, 0x500000, 3, 1},
+{0x35, 0x500000, 3, 1},
+{0x36, 0x500000, 3, 1},
+{0x37, 0x500000, 3, 1},
+{0x38, 0x500000, 3, 1},
+};

+ 111 - 0
NoPublic/ad7124_regs_config_b.c

@@ -0,0 +1,111 @@
+/*!
+ *****************************************************************************
+  @file:  ad7124_regs_config_b.c
+
+  @brief: Configuration file B for AD7124
+
+  @details:
+ -----------------------------------------------------------------------------
+Copyright (c) 2019 Analog Devices, Inc.
+
+All rights reserved.
+
+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.
+  - Modified versions of the software must be conspicuously marked as such.
+  - This software is licensed solely and exclusively for use with processors/
+    products manufactured by or for Analog Devices, Inc.
+  - This software may not be combined or merged with other code in any manner
+    that would cause the software to become subject to terms and conditions
+	which differ from those listed here.
+  - Neither the name of Analog Devices, Inc. nor the names of its contributors
+    may be used to endorse or promote products derived from this software without
+    specific prior written permission.
+  - The use of this software may or may not infringe the patent rights of one
+    or more patent holders.  This license does not release you from the
+	requirement that you obtain separate licenses from these patent holders
+	to use this software.
+
+THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-
+INFRINGEMENT, TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF
+CLAIMS OF INTELLECTUAL PROPERTY RIGHTS INFRINGEMENT; 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.
+
+20180927-7CBSD SLA
+
+*****************************************************************************/
+
+#include "ad7124_regs.h"
+
+const struct ad7124_st_reg ad7124_regs_config_b[AD7124_REG_NO] = {
+{0x00, 0x00, 1, 2},
+{0x01, 0x0708, 2, 1},
+{0x02, 0x000000, 3, 2},
+{0x03, 0x002010, 3, 1},
+{0x04, 0x0004, 2, 1},
+{0x05, 0x00, 1, 2},
+{0x06, 0x000000, 3, 2},
+{0x07, 0x000044, 3, 1},
+{0x08, 0x00, 1, 2},
+{0x09, 0x8043, 2, 1},
+{0x0A, 0x9085, 2, 1},
+{0x0B, 0x0001, 2, 1},
+{0x0C, 0x0001, 2, 1},
+{0x0D, 0x0001, 2, 1},
+{0x0E, 0x0001, 2, 1},
+{0x0F, 0x0001, 2, 1},
+{0x10, 0x0001, 2, 1},
+{0x11, 0x0001, 2, 1},
+{0x12, 0x0001, 2, 1},
+{0x13, 0x0001, 2, 1},
+{0x14, 0x0001, 2, 1},
+{0x15, 0x0001, 2, 1},
+{0x16, 0x0001, 2, 1},
+{0x17, 0x0001, 2, 1},
+{0x18, 0x0001, 2, 1},
+{0x19, 0x0877, 2, 1},
+{0x1A, 0x09E0, 2, 1},
+{0x1B, 0x0860, 2, 1},
+{0x1C, 0x0860, 2, 1},
+{0x1D, 0x0860, 2, 1},
+{0x1E, 0x0860, 2, 1},
+{0x1F, 0x0860, 2, 1},
+{0x20, 0x0860, 2, 1},
+{0x21, 0x060014, 3, 1},
+{0x22, 0x060014, 3, 1},
+{0x23, 0x060180, 3, 1},
+{0x24, 0x060180, 3, 1},
+{0x25, 0x060180, 3, 1},
+{0x26, 0x060180, 3, 1},
+{0x27, 0x060180, 3, 1},
+{0x28, 0x060180, 3, 1},
+{0x29, 0x800000, 3, 1},
+{0x2A, 0x800000, 3, 1},
+{0x2B, 0x800000, 3, 1},
+{0x2C, 0x800000, 3, 1},
+{0x2D, 0x800000, 3, 1},
+{0x2E, 0x800000, 3, 1},
+{0x2F, 0x800000, 3, 1},
+{0x30, 0x800000, 3, 1},
+{0x31, 0x500000, 3, 1},
+{0x32, 0x500000, 3, 1},
+{0x33, 0x500000, 3, 1},
+{0x34, 0x500000, 3, 1},
+{0x35, 0x500000, 3, 1},
+{0x36, 0x500000, 3, 1},
+{0x37, 0x500000, 3, 1},
+{0x38, 0x500000, 3, 1},
+};

+ 63 - 0
NoPublic/ad7124_regs_configs.h

@@ -0,0 +1,63 @@
+/*!
+ *****************************************************************************
+  @file:  ad7124_reg_app_config.h
+
+  @brief: 
+
+  @details:
+ -----------------------------------------------------------------------------
+Copyright (c) 2018-19 Analog Devices, Inc.
+
+All rights reserved.
+
+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.
+  - Modified versions of the software must be conspicuously marked as such.
+  - This software is licensed solely and exclusively for use with processors/
+    products manufactured by or for Analog Devices, Inc.
+  - This software may not be combined or merged with other code in any manner
+    that would cause the software to become subject to terms and conditions
+	which differ from those listed here.
+  - Neither the name of Analog Devices, Inc. nor the names of its contributors
+    may be used to endorse or promote products derived from this software without
+    specific prior written permission.
+  - The use of this software may or may not infringe the patent rights of one
+    or more patent holders.  This license does not release you from the
+	requirement that you obtain separate licenses from these patent holders
+	to use this software.
+
+THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-
+INFRINGEMENT, TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF
+CLAIMS OF INTELLECTUAL PROPERTY RIGHTS INFRINGEMENT; 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.
+
+20180927-7CBSD SLA
+
+*****************************************************************************/
+
+#ifndef AD7124_REGS_CONFIGS_H_
+#define AD7124_REGS_CONFIGS_H_
+
+#include "ad7124.h"
+
+/*
+ * Arrays holding the info for the AD7124 registers - address, initial value,
+ * size and access type.
+ */
+extern struct ad7124_st_reg ad7124_regs_config_a[AD7124_REG_NO];
+extern struct ad7124_st_reg ad7124_regs_config_b[AD7124_REG_NO];
+
+#endif /* AD7124_REGS_CONFIGS_H_ */

+ 133 - 0
NoPublic/ad7124_support.c

@@ -0,0 +1,133 @@
+/*!
+ *****************************************************************************
+  @file:  ad7124_support.c
+
+  @brief: Provides useful support functions for the AD7124 NoOS driver
+
+  @details:
+ -----------------------------------------------------------------------------
+Copyright (c) 2019 Analog Devices, Inc.  All rights reserved.
+
+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.
+  - Modified versions of the software must be conspicuously marked as such.
+  - This software is licensed solely and exclusively for use with processors/
+    products manufactured by or for Analog Devices, Inc.
+  - This software may not be combined or merged with other code in any manner
+    that would cause the software to become subject to terms and conditions
+	which differ from those listed here.
+  - Neither the name of Analog Devices, Inc. nor the names of its contributors
+    may be used to endorse or promote products derived from this software without
+    specific prior written permission.
+  - The use of this software may or may not infringe the patent rights of one
+    or more patent holders.  This license does not release you from the
+	requirement that you obtain separate licenses from these patent holders
+	to use this software.
+
+THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-
+INFRINGEMENT, TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF
+CLAIMS OF INTELLECTUAL PROPERTY RIGHTS INFRINGEMENT; 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.
+
+20180927-7CBSD SLA
+
+*****************************************************************************/
+
+#include <stdbool.h>
+#include "ad7124_support.h"
+
+// Public Functions
+/*
+ * @brief helper function get the setup setting for an ADC channel
+ *
+ * @param dev The device structure.
+ *
+ * @param channel ADC channel to get Setup for.
+ *
+ * @return value of setup field in channel configuration.
+ */
+uint8_t ad7124_get_channel_setup(struct ad7124_dev *dev, uint8_t channel)
+{
+	return (dev->regs[AD7124_Channel_0 + channel].value >> 12) & 0x7;
+}
+
+
+/*
+ * @brief helper function get the PGA setting for an ADC channel
+ *
+ * @param dev The device structure.
+ *
+ * @param channel ADC channel to get Setup for.
+ *
+ * @return value of PGA field in the setup for an ADC channel.
+ */
+uint8_t ad7124_get_channel_pga(struct ad7124_dev *dev, uint8_t channel)
+{
+	uint8_t setup = ad7124_get_channel_setup(dev, channel);
+
+	return (dev->regs[AD7124_Config_0 + setup].value) & 0x07;
+}
+
+
+/*
+ * @brief helper function get the bipolar setting for an ADC channel
+ *
+ * @param dev The device structure.
+ *
+ * @param channel ADC channel to get bipolar mode for.
+ *
+ * @return value of bipolar field in the setup for an ADC channel.
+ */
+bool ad7124_get_channel_bipolar(struct ad7124_dev *dev, uint8_t channel)
+{
+	uint8_t setup = ad7124_get_channel_setup(dev, channel);
+
+	return ((dev->regs[AD7124_Config_0 + setup].value >> 11) & 0x1) ? true : false;
+}
+
+
+/*
+ * @brief converts ADC sample value to voltage based on gain setting
+ *
+ * @param dev The device structure.
+ *
+ * @param channel ADC channel to get Setup for.
+ *
+ * @param sample Raw ADC sample
+ *
+ * @return Sample ADC value converted to voltage.
+ *
+ * @note The conversion equation is implemented for simplicity,
+ *       not for accuracy or performance
+ *
+ */
+float ad7124_convert_sample_to_voltage(struct ad7124_dev *dev, uint8_t channel, uint32_t sample)
+{
+	bool isBipolar = ad7124_get_channel_bipolar(dev, channel);
+	uint8_t channelPGA = ad7124_get_channel_pga(dev, channel);
+
+	float convertedValue;
+
+	if (isBipolar) {
+        convertedValue = ( ((float)sample / (1 << (AD7124_ADC_N_BITS -1))) -1 ) * \
+        		              (AD7124_REF_VOLTAGE / AD7124_PGA_GAIN(channelPGA));
+	} else {
+		convertedValue = ((float)sample * AD7124_REF_VOLTAGE)/(AD7124_PGA_GAIN(channelPGA) * \
+								                              (1 << AD7124_ADC_N_BITS));
+	}
+
+    return (convertedValue);
+}

+ 66 - 0
NoPublic/ad7124_support.h

@@ -0,0 +1,66 @@
+/*!
+ *****************************************************************************
+  @file:  ad7124_support.h
+
+  @brief: Provides useful support functions for the AD7124 NoOS driver
+
+  @details:
+ -----------------------------------------------------------------------------
+Copyright (c) 2019 Analog Devices, Inc.  All rights reserved.
+
+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.
+  - Modified versions of the software must be conspicuously marked as such.
+  - This software is licensed solely and exclusively for use with processors/
+    products manufactured by or for Analog Devices, Inc.
+  - This software may not be combined or merged with other code in any manner
+    that would cause the software to become subject to terms and conditions
+        which differ from those listed here.
+  - Neither the name of Analog Devices, Inc. nor the names of its contributors
+    may be used to endorse or promote products derived from this software
+without specific prior written permission.
+  - The use of this software may or may not infringe the patent rights of one
+    or more patent holders.  This license does not release you from the
+        requirement that you obtain separate licenses from these patent holders
+        to use this software.
+
+THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-
+INFRINGEMENT, TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF
+CLAIMS OF INTELLECTUAL PROPERTY RIGHTS INFRINGEMENT; 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.
+
+20180927-7CBSD SLA
+
+*****************************************************************************/
+
+#ifndef AD7124_SUPPORT_H_
+#define AD7124_SUPPORT_H_
+
+#include "ad7124.h"
+
+/* PGA Gain Value */
+#define AD7124_PGA_GAIN(x) (1 << (x))
+
+#define AD7124_REF_VOLTAGE 2.5
+#define AD7124_ADC_N_BITS 24
+
+uint8_t ad7124_get_channel_setup(struct ad7124_dev *dev, uint8_t channel);
+uint8_t ad7124_get_channel_pga(struct ad7124_dev *dev, uint8_t channel);
+bool ad7124_get_channel_bipolar(struct ad7124_dev *dev, uint8_t channel);
+float ad7124_convert_sample_to_voltage(struct ad7124_dev *dev, uint8_t channel,
+                                       uint32_t sample);
+
+#endif /* AD7124_SUPPORT_H_ */