Added ADC/DAC/LED test code.
continuous-integration/drone/push Build is passing Details

Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
Yilin Sun 2023-06-04 00:41:22 +08:00
parent 58b7d03a6a
commit db3d12cfa1
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
5 changed files with 186 additions and 22 deletions

View File

@ -4,9 +4,13 @@
#include <stdbool.h>
#include <stdint.h>
#define ATE_ADC_CH_IOREF 0
#define ATE_ADC_CH_IOREF_MASK (1U << ATE_ADC_CH_IOREF)
typedef enum {
ATE_RET_SUCCESS,
ATE_RET_FAIL,
ATE_RET_NOT_READY,
} ate_ret_t;
typedef enum {
@ -16,6 +20,12 @@ typedef enum {
ATE_GPIO_MODE_AF,
} ate_gpio_mode_t;
typedef enum {
ATE_LED_R,
ATE_LED_G,
ATE_LED_B,
} ate_led_t;
typedef ate_ret_t (*ate_i2c_read_t)(void *handle, uint8_t *data, uint8_t len);
typedef ate_ret_t (*ate_i2c_write_t)(void *handle, uint8_t *data, uint8_t len);
typedef ate_ret_t (*ate_delay_t)(void *handle, uint32_t msec);
@ -33,8 +43,13 @@ typedef struct {
} ate_t;
ate_ret_t ate_init(ate_t *ate);
ate_ret_t ate_led_set(ate_t *ate, ate_led_t led, bool value);
ate_ret_t ate_gpio_init(ate_t *ate, uint8_t pin, ate_gpio_mode_t mode);
ate_ret_t ate_gpio_read(ate_t *ate, uint8_t pin, bool *value);
ate_ret_t ate_gpio_write(ate_t *ate, uint8_t pin, bool value);
ate_ret_t ate_adc_configure(ate_t *ate, bool enable, uint8_t ch_mask);
ate_ret_t ate_adc_status(ate_t *ate, bool *enable);
ate_ret_t ate_adc_read(ate_t *ate, uint8_t ch, uint16_t *result);
ate_ret_t ate_dac_set(ate_t *ate, uint16_t da_value);
#endif // MPYATE_HOST_H

View File

@ -1,19 +1,44 @@
#ifndef MPYATE_COMMANDS_H
#define MPYATE_COMMANDS_H
#ifndef MPYATE_REGS_H
#define MPYATE_REGS_H
#define ATE_REG_CFG 0x00U
#define ATE_REG_SYS_CFG (0x00U)
#define ATE_REG_SYS_AUX (0x01U)
#define ATE_REG_SYS_VER (0x0EU)
#define ATE_REG_SYS_ID (0x0FU)
#define ATE_REG_GPIO_CFG 0x10U
#define ATE_REG_GPIO_DATA_OUT 0x11U
#define ATE_REG_GPIO_DATA_IN 0x92U
#define ATE_REG_SYS_CFG_RST_Pos (15U)
#define ATE_REG_SYS_CFG_RST_Msk (1U << ATE_REG_SYS_CFG_RST_Pos)
#define ATE_REG_VER 0xFEU
#define ATE_REG_ID 0xFFU
#define ATE_REG_SYS_AUX_GPIO_R_Pos (0U)
#define ATE_REG_SYS_AUX_GPIO_R_Msk (1U << ATE_REG_SYS_AUX_GPIO_R_Pos)
#define ATE_REG_CFG_RST_Pos 15
#define ATE_REG_CFG_RST_Msk (1U << ATE_REG_CFG_RST_Pos)
#define ATE_REG_SYS_AUX_GPIO_G_Pos (1U)
#define ATE_REG_SYS_AUX_GPIO_G_Msk (1U << ATE_REG_SYS_AUX_GPIO_G_Pos)
#define ATE_REG_GPIO_CFG_MODE_Pos 0
#define ATE_REG_SYS_AUX_GPIO_B_Pos (2U)
#define ATE_REG_SYS_AUX_GPIO_B_Msk (1U << ATE_REG_SYS_AUX_GPIO_B_Pos)
#define ATE_REG_GPIO_CFG (0x10U)
#define ATE_REG_GPIO_INPUT (0x11U)
#define ATE_REG_GPIO_OUTPUT (0x12U)
#define ATE_REG_GPIO_CFG_MODE_Pos (0U)
#define ATE_REG_GPIO_CFG_MODE_Msk (3U << ATE_REG_GPIO_CFG_MODE_Pos)
#endif // MPYATE_COMMANDS_H
#define ATE_REG_ADC_CTRL (0x20U)
#define ATE_REG_ADC_STAT (0x21U)
#define ATE_REG_ADC_CH(x) (0x22U + x)
#define ATE_REG_ADC_CTRL_CONV_Pos (15U)
#define ATE_REG_ADC_CTRL_CONV_Msk (1U << ATE_REG_ADC_CTRL_CONV_Pos)
#define ATE_REG_ADC_STAT_DONE_Pos (0U)
#define ATE_REG_ADC_STAT_DONE_Msk (1U << ATE_REG_ADC_STAT_DONE_Pos)
#define ATE_REG_DAC_CTRL (0x30U)
#define ATE_REG_DAC_DATA (0x31U)
#define ATE_REG_DAC_CTRL_BIAS_Pos (8U)
#define ATE_REG_DAC_CTRL_BIAS_Msk (1U << ATE_REG_DAC_CTRL_BIAS_Pos)
#endif // MPYATE_REGS_H

View File

@ -32,6 +32,25 @@ ate_ret_t ate_init(ate_t *ate) {
return ret;
}
ate_ret_t ate_led_set(ate_t *ate, ate_led_t led, bool value) {
ate_ret_t ret = ATE_RET_SUCCESS;
uint16_t sys_aux;
ret = ate_read_register(ate, ATE_REG_SYS_AUX, &sys_aux);
if (ret != ATE_RET_SUCCESS) {
return ret;
}
if (value) {
sys_aux |= (1U << led);
} else {
sys_aux &= ~(1U << led);
}
ret = ate_write_register(ate, ATE_REG_SYS_AUX, sys_aux);
return ret;
}
ate_ret_t ate_gpio_init(ate_t *ate, uint8_t pin, ate_gpio_mode_t mode) {
ate_ret_t ret = ATE_RET_SUCCESS;
@ -52,7 +71,7 @@ ate_ret_t ate_gpio_read(ate_t *ate, uint8_t pin, bool *value) {
ate_ret_t ret = ATE_RET_SUCCESS;
uint16_t pin_data;
ret = ate_read_register(ate, ATE_REG_GPIO_DATA_IN, &pin_data);
ret = ate_read_register(ate, ATE_REG_GPIO_INPUT, &pin_data);
if (ret != ATE_RET_SUCCESS) {
return ret;
}
@ -70,7 +89,7 @@ ate_ret_t ate_gpio_write(ate_t *ate, uint8_t pin, bool value) {
ate_ret_t ret = ATE_RET_SUCCESS;
uint16_t pin_data;
ret = ate_read_register(ate, ATE_REG_GPIO_DATA_OUT, &pin_data);
ret = ate_read_register(ate, ATE_REG_GPIO_OUTPUT, &pin_data);
if (ret != ATE_RET_SUCCESS) {
return ret;
}
@ -81,7 +100,77 @@ ate_ret_t ate_gpio_write(ate_t *ate, uint8_t pin, bool value) {
pin_data |= (1U << pin);
}
ret = ate_write_register(ate, ATE_REG_GPIO_DATA_OUT, pin_data);
ret = ate_write_register(ate, ATE_REG_GPIO_OUTPUT, pin_data);
return ret;
}
ate_ret_t ate_adc_configure(ate_t *ate, bool enable, uint8_t ch_mask) {
ate_ret_t ret = ATE_RET_SUCCESS;
uint16_t data;
ret = ate_read_register(ate, ATE_REG_ADC_CTRL, &data);
if (ret != ATE_RET_SUCCESS) {
return ret;
}
if (data & ATE_REG_ADC_CTRL_CONV_Msk) {
/* If ADC is started, stop first. */
ret = ate_write_register(ate, ATE_REG_ADC_CTRL, 0x0000U);
if (ret != ATE_RET_SUCCESS) {
return ret;
}
}
/* Clear status flag */
ret = ate_write_register(ate, ATE_REG_ADC_STAT, ATE_REG_ADC_STAT_DONE_Msk);
if (ret != ATE_RET_SUCCESS) {
return ret;
}
/* Enable ADC */
data = ATE_REG_ADC_CTRL_CONV_Msk | ch_mask;
ret = ate_write_register(ate, ATE_REG_ADC_CTRL, data);
return ret;
}
ate_ret_t ate_adc_status(ate_t *ate, bool *enable) {
ate_ret_t ret = ATE_RET_SUCCESS;
uint16_t data;
ret = ate_read_register(ate, ATE_REG_ADC_CTRL, &data);
if (ret != ATE_RET_SUCCESS) {
return ret;
}
*enable = (data & ATE_REG_ADC_CTRL_CONV_Msk) ? true : false;
return ret;
}
ate_ret_t ate_adc_read(ate_t *ate, uint8_t ch, uint16_t *result) {
ate_ret_t ret = ATE_RET_SUCCESS;
uint16_t data;
ret = ate_read_register(ate, ATE_REG_ADC_STAT, &data);
if (ret != ATE_RET_SUCCESS) {
return ret;
}
if ((data & ATE_REG_ADC_STAT_DONE_Msk) == 0U) {
return ATE_RET_NOT_READY;
}
ret = ate_read_register(ate, ATE_REG_ADC_CH(ch), result);
if (ret != ATE_RET_SUCCESS) {
return ret;
}
return ret;
}
ate_ret_t ate_dac_set(ate_t *ate, uint16_t da_value) {
ate_ret_t ret = ATE_RET_SUCCESS;
ret = ate_write_register(ate, ATE_REG_DAC_DATA, da_value);
return ret;
}
@ -89,14 +178,14 @@ static ate_ret_t ate_reset(ate_t *ate) {
ate_ret_t ret = ATE_RET_SUCCESS;
uint16_t cfg;
ret = ate_read_register(ate, ATE_REG_CFG, &cfg);
ret = ate_read_register(ate, ATE_REG_SYS_CFG, &cfg);
if (ret != ATE_RET_SUCCESS) {
return ret;
}
cfg |= ATE_REG_CFG_RST_Msk;
cfg |= ATE_REG_SYS_CFG_RST_Msk;
ret = ate_write_register(ate, ATE_REG_CFG, cfg);
ret = ate_write_register(ate, ATE_REG_SYS_CFG, cfg);
if (ret != ATE_RET_SUCCESS) {
return ret;
}
@ -107,7 +196,7 @@ static ate_ret_t ate_reset(ate_t *ate) {
}
static ate_ret_t ate_read_id(ate_t *ate, uint16_t *id) {
return ate_read_register(ate, ATE_REG_ID, id);
return ate_read_register(ate, ATE_REG_SYS_ID, id);
}
static ate_ret_t ate_read_register(ate_t *ate, uint8_t reg, uint16_t *data) {

View File

@ -61,7 +61,7 @@ void i2c_lowlevel_init(i2c_handle_type *handle) {
gpio_init(GPIOB, &pin_cfg);
/* Magic number: timing register value */
i2c_init(I2C1, 0x0F, 0x80504C4E);
i2c_init(I2C1, 0x0F, 0x30F03C6B);
i2c_own_address1_set(I2C1, I2C_ADDRESS_MODE_7BIT, 0xA0);
}

View File

@ -60,10 +60,45 @@ int main(void) {
printf("GPIO value: %d\r\n", pin_value);
dead_loop:
if (ate_adc_configure(&s_ate, true, ATE_ADC_CH_IOREF_MASK) != ATE_RET_SUCCESS) {
printf("Failed to enable ATE ADC.\r\n");
goto dead_loop;
}
uint16_t ioref_val;
uint16_t da_value = 0;
for (;;) {
/* -- */
__WFI();
ate_led_set(&s_ate, ATE_LED_G, true);
delay_ms(500);
ate_led_set(&s_ate, ATE_LED_G, false);
delay_ms(500);
ate_ret_t ret = ate_adc_read(&s_ate, ATE_ADC_CH_IOREF, &ioref_val);
if (ret == ATE_RET_NOT_READY) {
printf("ADC result is not ready.\r\n");
continue;
} else if (ret != ATE_RET_SUCCESS) {
printf("Failed to read ADC value.\r\n");
goto dead_loop;
}
printf("IOREF: %ld mV\r\n", ((uint32_t)ioref_val * 3300 * 2 / 4095));
ate_dac_set(&s_ate, da_value);
printf("DAC set to %dmV\r\n", (da_value * 3300 / 1023));
da_value += 32;
if (da_value > 1023) {
da_value = 0U;
}
}
dead_loop:
for (;;) {
/* -- */
}
}