diff --git a/.drone.yml b/.drone.yml index 94e5a4b..55f050c 100644 --- a/.drone.yml +++ b/.drone.yml @@ -14,4 +14,4 @@ steps: commands: - mkdir build && cd build - cmake -DCMAKE_TOOLCHAIN_FILE=arm-none-eabi.cmake .. - - make + - make at32f437_mpyate_host_FLASH.elf diff --git a/CMakeLists.txt b/CMakeLists.txt index ffd58ba..68425e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) -project(at32f437_start_template) +project(at32f437_mpyate_host) enable_language(CXX) enable_language(ASM) @@ -40,8 +40,10 @@ set(TARGET_SOURCES "SDK/libraries/drivers/src/at32f435_437_wdt.c" "SDK/libraries/drivers/src/at32f435_437_wwdt.c" "SDK/libraries/drivers/src/at32f435_437_xmc.c" + "SDK/middlewares/i2c_application_library/i2c_application.c" "board/at32f435_437_board.c" "board/at32f435_437_clock.c" + "src/app_ate_impl.c" "src/main.c" ) @@ -54,12 +56,14 @@ set(TARGET_C_INCLUDES "SDK/libraries/cmsis/cm4/core_support" "SDK/libraries/cmsis/cm4/device_support" "SDK/libraries/drivers/inc" + "SDK/middlewares/i2c_application_library" "board" "include" ) # Shared libraries linked with application set(TARGET_LIBS + "mpyate_host" "c" "m" "nosys" @@ -87,6 +91,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-common -fno-builtin -f set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") +add_subdirectory(lib/mpyate) + # Shared sources, includes and definitions add_compile_definitions(${TARGET_C_DEFINES}) include_directories(${TARGET_C_INCLUDES}) diff --git a/README.md b/README.md new file mode 100644 index 0000000..9e7734f --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# MPyATE Host + +[![Build Status](https://ci.minori.work/api/badges/imi415/Artery_AT32F437_Start_MPyATE_Host/status.svg)](https://ci.minori.work/imi415/Artery_AT32F437_Start_MPyATE_Host) \ No newline at end of file diff --git a/include/app_ate_impl.h b/include/app_ate_impl.h new file mode 100644 index 0000000..162b893 --- /dev/null +++ b/include/app_ate_impl.h @@ -0,0 +1,10 @@ +#ifndef APP_ATE_IMPL_H +#define APP_ATE_IMPL_H + +#include "mpyate_host.h" + +void ate_impl_i2c_init(void); +ate_ret_t ate_impl_i2c_read(void *handle, uint8_t *data, uint8_t len); +ate_ret_t ate_impl_i2c_write(void *handle, uint8_t *data, uint8_t len); + +#endif // APP_ATE_IMPL_H diff --git a/lib/mpyate/CMakeLists.txt b/lib/mpyate/CMakeLists.txt new file mode 100644 index 0000000..b71aa3a --- /dev/null +++ b/lib/mpyate/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.10) + +project(mpyate_host) + +set(ATE_HOST_SRCS + "src/mpyate_host.c" +) + +set(ATE_HOST_INCLUDES + "include" +) + +add_library(${PROJECT_NAME} ${ATE_HOST_SRCS}) +target_include_directories(${PROJECT_NAME} PUBLIC ${ATE_HOST_INCLUDES}) diff --git a/lib/mpyate/include/mpyate_host.h b/lib/mpyate/include/mpyate_host.h new file mode 100644 index 0000000..e52893f --- /dev/null +++ b/lib/mpyate/include/mpyate_host.h @@ -0,0 +1,27 @@ +#ifndef MPYATE_HOST_H +#define MPYATE_HOST_H + +#include + +typedef enum { + ATE_RET_SUCCESS, + ATE_RET_FAIL, +} ate_ret_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 struct { + ate_i2c_read_t read; + ate_i2c_write_t write; +} ate_ops_t; + +typedef struct { + ate_ops_t ops; + + void *user_data; +} ate_t; + +ate_ret_t ate_init(ate_t *ate); + +#endif // MPYATE_HOST_H diff --git a/lib/mpyate/include/private/mpyate_regs.h b/lib/mpyate/include/private/mpyate_regs.h new file mode 100644 index 0000000..d02f635 --- /dev/null +++ b/lib/mpyate/include/private/mpyate_regs.h @@ -0,0 +1,11 @@ +#ifndef MPYATE_COMMANDS_H +#define MPYATE_COMMANDS_H + +#define ATE_REG_CTRL 0x00U +#define ATE_REG_VER 0xFEU +#define ATE_REG_ID 0xFFU + +#define ATE_REG_CTRL_RST_Pos 15 +#define ATe_REG_CTRL_RST_Msk (1U << ATE_REG_CTRL_RST_Pos) + +#endif // MPYATE_COMMANDS_H diff --git a/lib/mpyate/src/mpyate_host.c b/lib/mpyate/src/mpyate_host.c new file mode 100644 index 0000000..1d1af5d --- /dev/null +++ b/lib/mpyate/src/mpyate_host.c @@ -0,0 +1,68 @@ +#include "mpyate_host.h" + +#include "private/mpyate_regs.h" + +#define ATE_COMPONENT_ID 0xEACE + +static ate_ret_t ate_read_id(ate_t *ate, uint16_t *id); + +static ate_ret_t ate_read_register(ate_t *ate, uint8_t reg, uint16_t *data); +static ate_ret_t ate_write_register(ate_t *ate, uint8_t reg, uint16_t data); + +ate_ret_t ate_init(ate_t *ate) { + ate_ret_t ret = ATE_RET_SUCCESS; + + uint16_t id; + + ret = ate_read_id(ate, &id); + if (ret != ATE_RET_SUCCESS) { + return ret; + } + + if (id != ATE_COMPONENT_ID) { + ret = ATE_RET_FAIL; + } + + return ret; +} + +static ate_ret_t ate_read_id(ate_t *ate, uint16_t *id) { + return ate_read_register(ate, ATE_REG_ID, id); +} + +static ate_ret_t ate_read_register(ate_t *ate, uint8_t reg, uint16_t *data) { + ate_ret_t ret = ATE_RET_SUCCESS; + + uint8_t tx_data[2] = {reg, 0x00}; + uint8_t rx_data[2] = {0x00, 0x00}; + + ret = ate->ops.write(ate->user_data, tx_data, 0x01); + if (ret != ATE_RET_SUCCESS) { + return ret; + } + + ret = ate->ops.read(ate->user_data, rx_data, 2); + if (ret != ATE_RET_SUCCESS) { + return ret; + } + + *data = rx_data[1] << 8U | rx_data[0]; + + return ret; +} + +static ate_ret_t ate_write_register(ate_t *ate, uint8_t reg, uint16_t data) { + ate_ret_t ret = ATE_RET_SUCCESS; + + uint8_t tx_data[3] = {reg, 0x00, 0x00}; + + tx_data[1] = data & 0xFFU; + tx_data[2] = (data >> 8U) & 0xFFU; + + ret = ate->ops.write(ate->user_data, tx_data, 0x03); + if (ret != ATE_RET_SUCCESS) { + return ret; + } + + return ret; +} \ No newline at end of file diff --git a/src/app_ate_impl.c b/src/app_ate_impl.c new file mode 100644 index 0000000..b67b623 --- /dev/null +++ b/src/app_ate_impl.c @@ -0,0 +1,62 @@ +/* SDK drivers */ +#include "at32f435_437_board.h" +#include "at32f435_437_clock.h" +#include "at32f435_437_i2c.h" + +/* Middleware */ +#include "i2c_application.h" + +/* ATE */ +#include "app_ate_impl.h" + +#define APP_ATE_I2C_ADDR (0x28U) +#define APP_ATE_I2C_ADDR_W (APP_ATE_I2C_ADDR << 1U) +#define APP_ATE_I2C_ADDR_R ((APP_ATE_I2C_ADDR << 1U) | 0x01U) + +static i2c_handle_type s_i2c_handle = { + .i2cx = I2C1, +}; + +void ate_impl_i2c_init(void) { + i2c_config(&s_i2c_handle); +} + +ate_ret_t ate_impl_i2c_read(void *handle, uint8_t *data, uint8_t len) { + if (i2c_master_receive(&s_i2c_handle, APP_ATE_I2C_ADDR_R, data, len, 0xFFFFFFFF) != I2C_OK) { + return ATE_RET_FAIL; + } + return ATE_RET_SUCCESS; +} + +ate_ret_t ate_impl_i2c_write(void *handle, uint8_t *data, uint8_t len) { + if (i2c_master_transmit(&s_i2c_handle, APP_ATE_I2C_ADDR_W, data, len, 0xFFFFFFFF) != I2C_OK) { + return ATE_RET_FAIL; + } + return ATE_RET_SUCCESS; +} + +void i2c_lowlevel_init(i2c_handle_type *handle) { + if (handle->i2cx == I2C1) { + crm_periph_clock_enable(CRM_I2C1_PERIPH_CLOCK, TRUE); + crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE); + + /* I2C1: PB8/PB9 */ + gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE8, GPIO_MUX_4); + gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE9, GPIO_MUX_4); + + gpio_init_type pin_cfg = { + .gpio_pins = GPIO_PINS_8 | GPIO_PINS_9, + .gpio_mode = GPIO_MODE_MUX, + .gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN, + .gpio_pull = GPIO_PULL_NONE, + .gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER, + }; + + gpio_init(GPIOB, &pin_cfg); + + /* Magic number: timing register value */ + i2c_init(I2C1, 0x0F, 0x80504C4E); + + i2c_own_address1_set(I2C1, I2C_ADDRESS_MODE_7BIT, 0xA0); + } +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index 06041ff..00523ad 100644 --- a/src/main.c +++ b/src/main.c @@ -1,9 +1,37 @@ +#include + +/* SDK drivers */ #include "at32f435_437_board.h" #include "at32f435_437_clock.h" +#include "at32f435_437_i2c.h" + +/* ATE */ +#include "app_ate_impl.h" + +static ate_t s_ate = { + .ops = + { + .read = ate_impl_i2c_read, + .write = ate_impl_i2c_write, + }, +}; int main(void) { system_clock_config(); at32_board_init(); + uart_print_init(115200); + + ate_impl_i2c_init(); + + if (ate_init(&s_ate) != ATE_RET_SUCCESS) { + printf("Failed to initialize ATE.\r\n"); + + goto dead_loop; + } + + printf("ATE initialized.\r\n"); + +dead_loop: for (;;) { /* -- */