diff --git a/lib/mpyate/include/mpyate_host.h b/lib/mpyate/include/mpyate_host.h index 6a03a6b..689fd29 100644 --- a/lib/mpyate/include/mpyate_host.h +++ b/lib/mpyate/include/mpyate_host.h @@ -4,9 +4,13 @@ #include #include +#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 diff --git a/lib/mpyate/include/private/mpyate_regs.h b/lib/mpyate/include/private/mpyate_regs.h index b82d895..e691acf 100644 --- a/lib/mpyate/include/private/mpyate_regs.h +++ b/lib/mpyate/include/private/mpyate_regs.h @@ -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 diff --git a/lib/mpyate/src/mpyate_host.c b/lib/mpyate/src/mpyate_host.c index 44d50f0..7e17a8d 100644 --- a/lib/mpyate/src/mpyate_host.c +++ b/lib/mpyate/src/mpyate_host.c @@ -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) { diff --git a/src/app_ate_impl.c b/src/app_ate_impl.c index 288b4ac..283e32d 100644 --- a/src/app_ate_impl.c +++ b/src/app_ate_impl.c @@ -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); } diff --git a/src/main.c b/src/main.c index 0efaff0..17c55b5 100644 --- a/src/main.c +++ b/src/main.c @@ -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 (;;) { + /* -- */ } }