diff --git a/.eide/eide.json b/.eide/eide.json index 0cf1bc1..6f73209 100644 --- a/.eide/eide.json +++ b/.eide/eide.json @@ -5,89 +5,16 @@ "srcDirs": [ ".eide/deps", "3rd-part", - "libraries/device", - "middlewares" + "middlewares", + "app", + "libraries/drivers", + "project", + "libraries/cmsis" ], "virtualFolder": { "name": "", "files": [], - "folders": [ - { - "name": "cmsis", - "files": [ - { - "path": "libraries/cmsis/cm4/device_support/startup/gcc/startup_at32f403a_407.s" - }, - { - "path": "libraries/cmsis/cm4/device_support/system_at32f403a_407.c" - } - ], - "folders": [] - }, - { - "name": "firmware", - "files": [ - { - "path": "libraries/drivers/src/at32f403a_407_adc.c" - }, - { - "path": "libraries/drivers/src/at32f403a_407_can.c" - }, - { - "path": "libraries/drivers/src/at32f403a_407_crm.c" - }, - { - "path": "libraries/drivers/src/at32f403a_407_debug.c" - }, - { - "path": "libraries/drivers/src/at32f403a_407_exint.c" - }, - { - "path": "libraries/drivers/src/at32f403a_407_flash.c" - }, - { - "path": "libraries/drivers/src/at32f403a_407_gpio.c" - }, - { - "path": "libraries/drivers/src/at32f403a_407_i2c.c" - }, - { - "path": "libraries/drivers/src/at32f403a_407_misc.c" - }, - { - "path": "libraries/drivers/src/at32f403a_407_pwc.c" - }, - { - "path": "libraries/drivers/src/at32f403a_407_tmr.c" - }, - { - "path": "libraries/drivers/src/at32f403a_407_usart.c" - } - ], - "folders": [] - }, - { - "name": "user", - "files": [ - { - "path": "project/src/at32f403a_407_int.c" - }, - { - "path": "project/src/at32f403a_407_wk_config.c" - }, - { - "path": "project/src/by_debug.c" - }, - { - "path": "project/src/eeprom.c" - }, - { - "path": "project/src/main.c" - } - ], - "folders": [] - } - ] + "folders": [] }, "outDir": "build", "deviceName": null, @@ -97,7 +24,11 @@ }, "targets": { "BC1C": { - "excludeList": [], + "excludeList": [ + "project/MDK_V5", + "libraries/cmsis/cm4/device_support/startup/iar", + "libraries/cmsis/cm4/device_support/startup/mdk" + ], "toolchain": "GCC", "compileConfig": { "cpuType": "Cortex-M4", @@ -140,7 +71,9 @@ ".cmsis/include", ".eide/deps", "3rd-part/dwt_delay", - "3rd-part/lwprintf" + "3rd-part/lwprintf", + "app", + "3rd-part/lwrb" ], "libList": [], "sourceDirList": [], diff --git a/3rd-part/lwrb/lwrb.c b/3rd-part/lwrb/lwrb.c new file mode 100644 index 0000000..348432c --- /dev/null +++ b/3rd-part/lwrb/lwrb.c @@ -0,0 +1,645 @@ +/** + * \file lwrb.c + * \brief Lightweight ring buffer + */ + +/* + * Copyright (c) 2023 Tilen MAJERLE + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * This file is part of LwRB - Lightweight ring buffer library. + * + * Author: Tilen MAJERLE + * Version: v3.0.0 + */ +#include "lwrb.h" + +/* Memory set and copy functions */ +#define BUF_MEMSET memset +#define BUF_MEMCPY memcpy + +#define BUF_IS_VALID(b) ((b) != NULL && (b)->buff != NULL && (b)->size > 0) +#define BUF_MIN(x, y) ((x) < (y) ? (x) : (y)) +#define BUF_MAX(x, y) ((x) > (y) ? (x) : (y)) +#define BUF_SEND_EVT(b, type, bp) \ + do { \ + if ((b)->evt_fn != NULL) { \ + (b)->evt_fn((void*)(b), (type), (bp)); \ + } \ + } while (0) + +/* Optional atomic opeartions */ +#ifdef LWRB_DISABLE_ATOMIC +#define LWRB_INIT(var, val) (var) = (val) +#define LWRB_LOAD(var, type) (var) +#define LWRB_STORE(var, val, type) (var) = (val) +#else +#define LWRB_INIT(var, val) atomic_init(&(var), (val)) +#define LWRB_LOAD(var, type) atomic_load_explicit(&(var), (type)) +#define LWRB_STORE(var, val, type) atomic_store_explicit(&(var), (val), (type)) +#endif + +/** + * \brief Initialize buffer handle to default values with size and buffer data array + * \param[in] buff: Ring buffer instance + * \param[in] buffdata: Pointer to memory to use as buffer data + * \param[in] size: Size of `buffdata` in units of bytes + * Maximum number of bytes buffer can hold is `size - 1` + * \return `1` on success, `0` otherwise + */ +uint8_t +lwrb_init(lwrb_t* buff, void* buffdata, lwrb_sz_t size) { + if (buff == NULL || buffdata == NULL || size == 0) { + return 0; + } + + buff->evt_fn = NULL; + buff->size = size; + buff->buff = buffdata; + LWRB_INIT(buff->w, 0); + LWRB_INIT(buff->r, 0); + return 1; +} + +/** + * \brief Check if buff is initialized and ready to use + * \param[in] buff: Ring buffer instance + * \return `1` if ready, `0` otherwise + */ +uint8_t +lwrb_is_ready(lwrb_t* buff) { + return BUF_IS_VALID(buff); +} + +/** + * \brief Free buffer memory + * \note Since implementation does not use dynamic allocation, + * it just sets buffer handle to `NULL` + * \param[in] buff: Ring buffer instance + */ +void +lwrb_free(lwrb_t* buff) { + if (BUF_IS_VALID(buff)) { + buff->buff = NULL; + } +} + +/** + * \brief Set event function callback for different buffer operations + * \param[in] buff: Ring buffer instance + * \param[in] evt_fn: Callback function + */ +void +lwrb_set_evt_fn(lwrb_t* buff, lwrb_evt_fn evt_fn) { + if (BUF_IS_VALID(buff)) { + buff->evt_fn = evt_fn; + } +} + +/** + * \brief Write data to buffer. + * Copies data from `data` array to buffer and marks buffer as full for maximum `btw` number of bytes + * + * \param[in] buff: Ring buffer instance + * \param[in] data: Pointer to data to write into buffer + * \param[in] btw: Number of bytes to write + * \return Number of bytes written to buffer. + * When returned value is less than `btw`, there was no enough memory available + * to copy full data array. + */ +lwrb_sz_t +lwrb_write(lwrb_t* buff, const void* data, lwrb_sz_t btw) { + lwrb_sz_t written = 0; + + if (lwrb_write_ex(buff, data, btw, &written, 0)) { + return written; + } + return 0; +} + +/** + * \brief Write extended functionality + * + * \param buff: Ring buffer instance + * \param data: Pointer to data to write into buffer + * \param btw: Number of bytes to write + * \param bw: Output pointer to write number of bytes written + * \param flags: Optional flags. + * \ref LWRB_FLAG_WRITE_ALL: Request to write all data (up to btw). + * Will early return if no memory available + * \return `1` if write operation OK, `0` otherwise + */ +uint8_t +lwrb_write_ex(lwrb_t* buff, const void* data, lwrb_sz_t btw, lwrb_sz_t* bw, uint16_t flags) { + lwrb_sz_t tocopy, free, buff_w_ptr; + const uint8_t* d = data; + + if (!BUF_IS_VALID(buff) || data == NULL || btw == 0) { + return 0; + } + + /* Calculate maximum number of bytes available to write */ + free = lwrb_get_free(buff); + /* If no memory, or if user wants to write ALL data but no enough space, exit early */ + if (free == 0 || (free < btw && flags & LWRB_FLAG_WRITE_ALL)) { + return 0; + } + btw = BUF_MIN(free, btw); + buff_w_ptr = LWRB_LOAD(buff->w, memory_order_acquire); + + /* Step 1: Write data to linear part of buffer */ + tocopy = BUF_MIN(buff->size - buff_w_ptr, btw); + BUF_MEMCPY(&buff->buff[buff_w_ptr], d, tocopy); + buff_w_ptr += tocopy; + btw -= tocopy; + + /* Step 2: Write data to beginning of buffer (overflow part) */ + if (btw > 0) { + BUF_MEMCPY(buff->buff, &d[tocopy], btw); + buff_w_ptr = btw; + } + + /* Step 3: Check end of buffer */ + if (buff_w_ptr >= buff->size) { + buff_w_ptr = 0; + } + + /* + * Write final value to the actual running variable. + * This is to ensure no read operation can access intermediate data + */ + LWRB_STORE(buff->w, buff_w_ptr, memory_order_release); + + BUF_SEND_EVT(buff, LWRB_EVT_WRITE, tocopy + btw); + if (bw != NULL) { + *bw = tocopy + btw; + } + return 1; +} + +/** + * \brief Read data from buffer. + * Copies data from buffer to `data` array and marks buffer as free for maximum `btr` number of bytes + * + * \param[in] buff: Ring buffer instance + * \param[out] data: Pointer to output memory to copy buffer data to + * \param[in] btr: Number of bytes to read + * \return Number of bytes read and copied to data array + */ +lwrb_sz_t +lwrb_read(lwrb_t* buff, void* data, lwrb_sz_t btr) { + lwrb_sz_t read = 0; + + if (lwrb_read_ex(buff, data, btr, &read, 0)) { + return read; + } + return 0; +} + +/** + * \brief Write extended functionality + * + * \param buff: Ring buffer instance + * \param data: Pointer to memory to write read data from buffer + * \param btr: Number of bytes to read + * \param br: Output pointer to write number of bytes read + * \param flags: Optional flags + * \ref LWRB_FLAG_READ_ALL: Request to read all data (up to btr). + * Will early return if no enough bytes in the buffer + * \return `1` if read operation OK, `0` otherwise + */ +uint8_t +lwrb_read_ex(lwrb_t* buff, void* data, lwrb_sz_t btr, lwrb_sz_t* br, uint16_t flags) { + lwrb_sz_t tocopy, full, buff_r_ptr; + uint8_t* d = data; + + if (!BUF_IS_VALID(buff) || data == NULL || btr == 0) { + return 0; + } + + /* Calculate maximum number of bytes available to read */ + full = lwrb_get_full(buff); + if (full == 0 || (full < btr && (flags & LWRB_FLAG_READ_ALL))) { + return 0; + } + btr = BUF_MIN(full, btr); + buff_r_ptr = LWRB_LOAD(buff->r, memory_order_acquire); + + /* Step 1: Read data from linear part of buffer */ + tocopy = BUF_MIN(buff->size - buff_r_ptr, btr); + BUF_MEMCPY(d, &buff->buff[buff_r_ptr], tocopy); + buff_r_ptr += tocopy; + btr -= tocopy; + + /* Step 2: Read data from beginning of buffer (overflow part) */ + if (btr > 0) { + BUF_MEMCPY(&d[tocopy], buff->buff, btr); + buff_r_ptr = btr; + } + + /* Step 3: Check end of buffer */ + if (buff_r_ptr >= buff->size) { + buff_r_ptr = 0; + } + + /* + * Write final value to the actual running variable. + * This is to ensure no write operation can access intermediate data + */ + LWRB_STORE(buff->r, buff_r_ptr, memory_order_release); + + BUF_SEND_EVT(buff, LWRB_EVT_READ, tocopy + btr); + if (br != NULL) { + *br = tocopy + btr; + } + return 1; +} + +/** + * \brief Read from buffer without changing read pointer (peek only) + * \param[in] buff: Ring buffer instance + * \param[in] skip_count: Number of bytes to skip before reading data + * \param[out] data: Pointer to output memory to copy buffer data to + * \param[in] btp: Number of bytes to peek + * \return Number of bytes peeked and written to output array + */ +lwrb_sz_t +lwrb_peek(const lwrb_t* buff, lwrb_sz_t skip_count, void* data, lwrb_sz_t btp) { + lwrb_sz_t full, tocopy, r; + uint8_t* d = data; + + if (!BUF_IS_VALID(buff) || data == NULL || btp == 0) { + return 0; + } + + /* + * Calculate maximum number of bytes available to read + * and check if we can even fit to it + */ + full = lwrb_get_full(buff); + if (skip_count >= full) { + return 0; + } + r = LWRB_LOAD(buff->r, memory_order_relaxed); + r += skip_count; + full -= skip_count; + if (r >= buff->size) { + r -= buff->size; + } + + /* Check maximum number of bytes available to read after skip */ + btp = BUF_MIN(full, btp); + if (btp == 0) { + return 0; + } + + /* Step 1: Read data from linear part of buffer */ + tocopy = BUF_MIN(buff->size - r, btp); + BUF_MEMCPY(d, &buff->buff[r], tocopy); + btp -= tocopy; + + /* Step 2: Read data from beginning of buffer (overflow part) */ + if (btp > 0) { + BUF_MEMCPY(&d[tocopy], buff->buff, btp); + } + return tocopy + btp; +} + +/** + * \brief Get available size in buffer for write operation + * \param[in] buff: Ring buffer instance + * \return Number of free bytes in memory + */ +lwrb_sz_t +lwrb_get_free(const lwrb_t* buff) { + lwrb_sz_t size, w, r; + + if (!BUF_IS_VALID(buff)) { + return 0; + } + + /* + * Copy buffer pointers to local variables with atomic access. + * + * To ensure thread safety (only when in single-entry, single-exit FIFO mode use case), + * it is important to write buffer r and w values to local w and r variables. + * + * Local variables will ensure below if statements will always use the same value, + * even if buff->w or buff->r get changed during interrupt processing. + * + * They may change during load operation, important is that + * they do not change during if-elseif-else operations following these assignments. + * + * lwrb_get_free is only called for write purpose, and when in FIFO mode, then: + * - buff->w pointer will not change by another process/interrupt because we are in write mode just now + * - buff->r pointer may change by another process. If it gets changed after buff->r has been loaded to local variable, + * buffer will see "free size" less than it actually is. This is not a problem, application can + * always try again to write more data to remaining free memory that was read just during copy operation + */ + w = LWRB_LOAD(buff->w, memory_order_relaxed); + r = LWRB_LOAD(buff->r, memory_order_relaxed); + + if (w == r) { + size = buff->size; + } else if (r > w) { + size = r - w; + } else { + size = buff->size - (w - r); + } + + /* Buffer free size is always 1 less than actual size */ + return size - 1; +} + +/** + * \brief Get number of bytes currently available in buffer + * \param[in] buff: Ring buffer instance + * \return Number of bytes ready to be read + */ +lwrb_sz_t +lwrb_get_full(const lwrb_t* buff) { + lwrb_sz_t size, w, r; + + if (!BUF_IS_VALID(buff)) { + return 0; + } + + /* + * Copy buffer pointers to local variables. + * + * To ensure thread safety (only when in single-entry, single-exit FIFO mode use case), + * it is important to write buffer r and w values to local w and r variables. + * + * Local variables will ensure below if statements will always use the same value, + * even if buff->w or buff->r get changed during interrupt processing. + * + * They may change during load operation, important is that + * they do not change during if-elseif-else operations following these assignments. + * + * lwrb_get_full is only called for read purpose, and when in FIFO mode, then: + * - buff->r pointer will not change by another process/interrupt because we are in read mode just now + * - buff->w pointer may change by another process. If it gets changed after buff->w has been loaded to local variable, + * buffer will see "full size" less than it really is. This is not a problem, application can + * always try again to read more data from remaining full memory that was written just during copy operation + */ + w = LWRB_LOAD(buff->w, memory_order_relaxed); + r = LWRB_LOAD(buff->r, memory_order_relaxed); + + if (w == r) { + size = 0; + } else if (w > r) { + size = w - r; + } else { + size = buff->size - (r - w); + } + return size; +} + +/** + * \brief Resets buffer to default values. Buffer size is not modified + * \note This function is not thread safe. + * When used, application must ensure there is no active read/write operation + * \param[in] buff: Ring buffer instance + */ +void +lwrb_reset(lwrb_t* buff) { + if (BUF_IS_VALID(buff)) { + LWRB_STORE(buff->w, 0, memory_order_release); + LWRB_STORE(buff->r, 0, memory_order_release); + BUF_SEND_EVT(buff, LWRB_EVT_RESET, 0); + } +} + +/** + * \brief Get linear address for buffer for fast read + * \param[in] buff: Ring buffer instance + * \return Linear buffer start address + */ +void* +lwrb_get_linear_block_read_address(const lwrb_t* buff) { + if (!BUF_IS_VALID(buff)) { + return NULL; + } + return &buff->buff[buff->r]; +} + +/** + * \brief Get length of linear block address before it overflows for read operation + * \param[in] buff: Ring buffer instance + * \return Linear buffer size in units of bytes for read operation + */ +lwrb_sz_t +lwrb_get_linear_block_read_length(const lwrb_t* buff) { + lwrb_sz_t len, w, r; + + if (!BUF_IS_VALID(buff)) { + return 0; + } + + /* + * Use temporary values in case they are changed during operations. + * See lwrb_buff_free or lwrb_buff_full functions for more information why this is OK. + */ + w = LWRB_LOAD(buff->w, memory_order_relaxed); + r = LWRB_LOAD(buff->r, memory_order_relaxed); + + if (w > r) { + len = w - r; + } else if (r > w) { + len = buff->size - r; + } else { + len = 0; + } + return len; +} + +/** + * \brief Skip (ignore; advance read pointer) buffer data + * Marks data as read in the buffer and increases free memory for up to `len` bytes + * + * \note Useful at the end of streaming transfer such as DMA + * \param[in] buff: Ring buffer instance + * \param[in] len: Number of bytes to skip and mark as read + * \return Number of bytes skipped + */ +lwrb_sz_t +lwrb_skip(lwrb_t* buff, lwrb_sz_t len) { + lwrb_sz_t full, r; + + if (!BUF_IS_VALID(buff) || len == 0) { + return 0; + } + + full = lwrb_get_full(buff); + len = BUF_MIN(len, full); + r = LWRB_LOAD(buff->r, memory_order_acquire); + r += len; + if (r >= buff->size) { + r -= buff->size; + } + LWRB_STORE(buff->r, r, memory_order_release); + BUF_SEND_EVT(buff, LWRB_EVT_READ, len); + return len; +} + +/** + * \brief Get linear address for buffer for fast read + * \param[in] buff: Ring buffer instance + * \return Linear buffer start address + */ +void* +lwrb_get_linear_block_write_address(const lwrb_t* buff) { + if (!BUF_IS_VALID(buff)) { + return NULL; + } + return &buff->buff[buff->w]; +} + +/** + * \brief Get length of linear block address before it overflows for write operation + * \param[in] buff: Ring buffer instance + * \return Linear buffer size in units of bytes for write operation + */ +lwrb_sz_t +lwrb_get_linear_block_write_length(const lwrb_t* buff) { + lwrb_sz_t len, w, r; + + if (!BUF_IS_VALID(buff)) { + return 0; + } + + /* + * Use temporary values in case they are changed during operations. + * See lwrb_buff_free or lwrb_buff_full functions for more information why this is OK. + */ + w = LWRB_LOAD(buff->w, memory_order_relaxed); + r = LWRB_LOAD(buff->r, memory_order_relaxed); + + if (w >= r) { + len = buff->size - w; + /* + * When read pointer is 0, + * maximal length is one less as if too many bytes + * are written, buffer would be considered empty again (r == w) + */ + if (r == 0) { + /* + * Cannot overflow: + * - If r is not 0, statement does not get called + * - buff->size cannot be 0 and if r is 0, len is greater 0 + */ + --len; + } + } else { + len = r - w - 1; + } + return len; +} + +/** + * \brief Advance write pointer in the buffer. + * Similar to skip function but modifies write pointer instead of read + * + * \note Useful when hardware is writing to buffer and application needs to increase number + * of bytes written to buffer by hardware + * \param[in] buff: Ring buffer instance + * \param[in] len: Number of bytes to advance + * \return Number of bytes advanced for write operation + */ +lwrb_sz_t +lwrb_advance(lwrb_t* buff, lwrb_sz_t len) { + lwrb_sz_t free, w; + + if (!BUF_IS_VALID(buff) || len == 0) { + return 0; + } + + /* Use local variables before writing back to main structure */ + free = lwrb_get_free(buff); + len = BUF_MIN(len, free); + w = LWRB_LOAD(buff->w, memory_order_acquire); + w += len; + if (w >= buff->size) { + w -= buff->size; + } + LWRB_STORE(buff->w, w, memory_order_release); + BUF_SEND_EVT(buff, LWRB_EVT_WRITE, len); + return len; +} + +/** + * \brief Searches for a *needle* in an array, starting from given offset. + * + * \note This function is not thread-safe. + * + * \param buff: Ring buffer to search for needle in + * \param bts: Constant byte array sequence to search for in a buffer + * \param len: Length of the \arg bts array + * \param start_offset: Start offset in the buffer + * \param found_idx: Pointer to variable to write index in array where bts has been found + * Must not be set to `NULL` + * \return `1` if \arg bts found, `0` otherwise + */ +uint8_t +lwrb_find(const lwrb_t* buff, const void* bts, lwrb_sz_t len, lwrb_sz_t start_offset, lwrb_sz_t* found_idx) { + lwrb_sz_t full, r, max_x; + uint8_t found = 0; + const uint8_t* needle = bts; + + if (!BUF_IS_VALID(buff) || needle == NULL || len == 0 || found_idx == NULL) { + return 0; + } + *found_idx = 0; + + full = lwrb_get_full(buff); + /* Verify initial conditions */ + if (full < (len + start_offset)) { + return 0; + } + + /* Max number of for loops is buff_full - input_len - start_offset of buffer length */ + max_x = full - len; + for (lwrb_sz_t skip_x = start_offset; !found && skip_x <= max_x; ++skip_x) { + found = 1; /* Found by default */ + + /* Prepare the starting point for reading */ + r = buff->r + skip_x; + if (r >= buff->size) { + r -= buff->size; + } + + /* Search in the buffer */ + for (lwrb_sz_t i = 0; i < len; ++i) { + if (buff->buff[r] != needle[i]) { + found = 0; + break; + } + if (++r >= buff->size) { + r = 0; + } + } + if (found) { + *found_idx = skip_x; + } + } + return found; +} diff --git a/3rd-part/lwrb/lwrb.h b/3rd-part/lwrb/lwrb.h new file mode 100644 index 0000000..0339e03 --- /dev/null +++ b/3rd-part/lwrb/lwrb.h @@ -0,0 +1,149 @@ +/** + * \file lwrb.h + * \brief LwRB - Lightweight ring buffer + */ + +/* + * Copyright (c) 2023 Tilen MAJERLE + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * This file is part of LwRB - Lightweight ring buffer library. + * + * Author: Tilen MAJERLE + * Version: v3.0.0-rc1 + */ +#ifndef LWRB_HDR_H +#define LWRB_HDR_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * \defgroup LWRB Lightweight ring buffer manager + * \brief Lightweight ring buffer manager + * \{ + */ + +#if !defined(LWRB_DISABLE_ATOMIC) || __DOXYGEN__ +#include + +/** + * \brief Atomic type for size variable. + * Default value is set to be `unsigned 32-bits` type + */ +typedef atomic_ulong lwrb_sz_atomic_t; + +/** + * \brief Size variable for all library operations. + * Default value is set to be `unsigned 32-bits` type + */ +typedef unsigned long lwrb_sz_t; +#else +typedef unsigned long lwrb_sz_atomic_t; +typedef unsigned long lwrb_sz_t; +#endif + +/** + * \brief Event type for buffer operations + */ +typedef enum { + LWRB_EVT_READ, /*!< Read event */ + LWRB_EVT_WRITE, /*!< Write event */ + LWRB_EVT_RESET, /*!< Reset event */ +} lwrb_evt_type_t; + +/** + * \brief Buffer structure forward declaration + */ +struct lwrb; + +/** + * \brief Event callback function type + * \param[in] buff: Buffer handle for event + * \param[in] evt: Event type + * \param[in] bp: Number of bytes written or read (when used), depends on event type + */ +typedef void (*lwrb_evt_fn)(struct lwrb* buff, lwrb_evt_type_t evt, lwrb_sz_t bp); + +/* List of flags */ +#define LWRB_FLAG_READ_ALL ((uint16_t)0x0001) +#define LWRB_FLAG_WRITE_ALL ((uint16_t)0x0001) + +/** + * \brief Buffer structure + */ +typedef struct lwrb { + uint8_t* buff; /*!< Pointer to buffer data. Buffer is considered initialized when `buff != NULL` and `size > 0` */ + lwrb_sz_t size; /*!< Size of buffer data. Size of actual buffer is `1` byte less than value holds */ + lwrb_sz_atomic_t r; /*!< Next read pointer. Buffer is considered empty when `r == w` and full when `w == r - 1` */ + lwrb_sz_atomic_t w; /*!< Next write pointer. Buffer is considered empty when `r == w` and full when `w == r - 1` */ + lwrb_evt_fn evt_fn; /*!< Pointer to event callback function */ +} lwrb_t; + +uint8_t lwrb_init(lwrb_t* buff, void* buffdata, lwrb_sz_t size); +uint8_t lwrb_is_ready(lwrb_t* buff); +void lwrb_free(lwrb_t* buff); +void lwrb_reset(lwrb_t* buff); +void lwrb_set_evt_fn(lwrb_t* buff, lwrb_evt_fn fn); + +/* Read/Write functions */ +lwrb_sz_t lwrb_write(lwrb_t* buff, const void* data, lwrb_sz_t btw); +lwrb_sz_t lwrb_read(lwrb_t* buff, void* data, lwrb_sz_t btr); +lwrb_sz_t lwrb_peek(const lwrb_t* buff, lwrb_sz_t skip_count, void* data, lwrb_sz_t btp); + +/* Extended read/write functions */ +uint8_t lwrb_write_ex(lwrb_t* buff, const void* data, lwrb_sz_t btw, lwrb_sz_t* bw, uint16_t flags); +uint8_t lwrb_read_ex(lwrb_t* buff, void* data, lwrb_sz_t btr, lwrb_sz_t* br, uint16_t flags); + +/* Buffer size information */ +lwrb_sz_t lwrb_get_free(const lwrb_t* buff); +lwrb_sz_t lwrb_get_full(const lwrb_t* buff); + +/* Read data block management */ +void* lwrb_get_linear_block_read_address(const lwrb_t* buff); +lwrb_sz_t lwrb_get_linear_block_read_length(const lwrb_t* buff); +lwrb_sz_t lwrb_skip(lwrb_t* buff, lwrb_sz_t len); + +/* Write data block management */ +void* lwrb_get_linear_block_write_address(const lwrb_t* buff); +lwrb_sz_t lwrb_get_linear_block_write_length(const lwrb_t* buff); +lwrb_sz_t lwrb_advance(lwrb_t* buff, lwrb_sz_t len); + +/* Search in buffer */ +uint8_t lwrb_find(const lwrb_t* buff, const void* bts, lwrb_sz_t len, lwrb_sz_t start_offset, lwrb_sz_t* found_idx); +lwrb_sz_t lwrb_overwrite(lwrb_t* buff, const void* data, lwrb_sz_t btw); +lwrb_sz_t lwrb_move(lwrb_t* dest, lwrb_t* src); + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LWRB_HDR_H */ diff --git a/BC1C.ATWP b/BC1C.ATWP index 0dee0d4..b09cdc0 100644 --- a/BC1C.ATWP +++ b/BC1C.ATWP @@ -5,15 +5,6 @@ AT32F403ARCT7 LQFP64 - - - - - - - - - @@ -40,6 +31,17 @@ + + + + + + + + + + + @@ -127,7 +129,6 @@ 0;0;0 0;0;0 0;0;0 - 0;0;0 0;0;0 1;0;0 0;0;0 @@ -175,7 +176,6 @@ - @@ -216,6 +216,6 @@ 0x200 0x400 false - + V2.1.8 diff --git a/app/by_motion.c b/app/by_motion.c new file mode 100644 index 0000000..496b870 --- /dev/null +++ b/app/by_motion.c @@ -0,0 +1,54 @@ +#include "by_motion.h" + +#include +#include + +#define D_X (0.18f) // 底盘 Y 轴上两轮中心的间距 +#define D_Y (0.25f) // 底盘 X 轴上两轮中心的间距 +#define RX_RY ((D_X + D_Y) / 2.f) + +#define FP2U16_SCALE (1000.f) // 浮点转存为整数缩放尺度,所有设备该参数需对应 +#define FP2U16(x) ((int16_t)(x * FP2U16_SCALE)) // 浮点转存为整数 + +/********************************************** + * v_1 = v_{ty} + v_{tx} - (r_x + r_y) * \omega + * v_2 = v_{ty} - v_{tx} + (r_x + r_y) * \omega + * v_3 = v_{ty} + v_{tx} + (r_x + r_y) * \omega + * v_4 = v_{ty} - v_{tx} - (r_x + r_y) * \omega + **********************************************/ + +/*** 各轮转速,左上角为 1 号,顺时针标号 ***/ +float v_wheel[4] = {0.f}; + +/** 目标速度 **/ +motion_speed_type motion_speed_struct; + +/** 下发数据包 **/ +int16_t motion_speed_data[4] = {0}; + +void by_motion_init(void) +{ + memset(&motion_speed_struct, 0, sizeof(motion_speed_struct)); + memset(v_wheel, 0, sizeof(v_wheel)); +} + +void by_motion_calc_speed(motion_speed_type *speed) +{ + motion_speed_struct = *speed; + + v_wheel[0] = speed->v_x + speed->v_y - RX_RY * speed->v_w; + v_wheel[1] = speed->v_x - speed->v_y + RX_RY * speed->v_w; + v_wheel[2] = speed->v_x + speed->v_y + RX_RY * speed->v_w; + v_wheel[3] = speed->v_x - speed->v_y - RX_RY * speed->v_w; +} + +/** + * @brief + * + */ +void by_motion_pack_speed(void) +{ + for (uint8_t i = 0; i < 4; i++) { + motion_speed_data[i] = FP2U16(v_wheel[i]); + } +} \ No newline at end of file diff --git a/app/by_motion.h b/app/by_motion.h new file mode 100644 index 0000000..bc0039c --- /dev/null +++ b/app/by_motion.h @@ -0,0 +1,12 @@ +#ifndef _BY_MOTION_H__ +#define _BY_MOTION_H__ + +#include "at32f403a_407.h" + +typedef struct motion_speed_type { + float v_x; + float v_y; + float v_w; +} motion_speed_type; + +#endif diff --git a/libraries/device/bmi088/by_bmi088.c b/libraries/device/bmi088/by_bmi088.c deleted file mode 100644 index f8f7b43..0000000 --- a/libraries/device/bmi088/by_bmi088.c +++ /dev/null @@ -1,3 +0,0 @@ -#include "by_bmi088.h" - - diff --git a/libraries/device/bmi088/by_bmi088.h b/libraries/device/bmi088/by_bmi088.h deleted file mode 100644 index b181317..0000000 --- a/libraries/device/bmi088/by_bmi088.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _BY_BMI088_H__ -#define _BY_BMI088_H__ - -#include - -#define BMI088_GYRO_ADDR (0x68) -#define BMI088_ACC_ADDR (0x18) - -void by_bmi088_init(void); - -void by_bmi088_read_reg(uint8_t addr, uint8_t* buf, uint8_t len); -void by_bmi088_write_reg(uint8_t addr, uint8_t* buf, uint8_t len); - -#endif diff --git a/libraries/drivers/inc/at32f403a_407_acc.h b/libraries/drivers/inc/at32f403a_407_acc.h new file mode 100644 index 0000000..2955fd4 --- /dev/null +++ b/libraries/drivers/inc/at32f403a_407_acc.h @@ -0,0 +1,201 @@ +/** + ************************************************************************** + * @file at32f403a_407_acc.h + * @brief at32f403a_407 acc header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_ACC_H +#define __AT32F403A_407_ACC_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @addtogroup ACC + * @{ + */ + +/** @defgroup ACC_exported_constants + * @{ + */ + +#define ACC_CAL_HICKCAL ((uint16_t)0x0000) /*!< acc hick calibration */ +#define ACC_CAL_HICKTRIM ((uint16_t)0x0002) /*!< acc hick trim */ + +#define ACC_RSLOST_FLAG ((uint16_t)0x0002) /*!< acc reference signal lost error flag */ +#define ACC_CALRDY_FLAG ((uint16_t)0x0001) /*!< acc internal high-speed clock calibration ready error flag */ + +#define ACC_CALRDYIEN_INT ((uint16_t)0x0020) /*!< acc internal high-speed clock calibration ready interrupt enable */ +#define ACC_EIEN_INT ((uint16_t)0x0010) /*!< acc reference signal lost interrupt enable */ + +/** + * @} + */ + +/** @defgroup ACC_exported_types + * @{ + */ + +/** + * @brief type define acc register all + */ +typedef struct +{ + + /** + * @brief acc sts register, offset:0x00 + */ + union + { + __IO uint32_t sts; + struct + { + __IO uint32_t calrdy : 1; /* [0] */ + __IO uint32_t rslost : 1; /* [1] */ + __IO uint32_t reserved1 : 30;/* [31:2] */ + } sts_bit; + }; + + /** + * @brief acc ctrl1 register, offset:0x04 + */ + union + { + __IO uint32_t ctrl1; + struct + { + __IO uint32_t calon : 1; /* [0] */ + __IO uint32_t entrim : 1; /* [1] */ + __IO uint32_t reserved1 : 2; /* [3:2] */ + __IO uint32_t eien : 1; /* [4] */ + __IO uint32_t calrdyien : 1; /* [5] */ + __IO uint32_t reserved2 : 2; /* [7:6] */ + __IO uint32_t step : 4; /* [11:8] */ + __IO uint32_t reserved3 : 20;/* [31:12] */ + } ctrl1_bit; + }; + + /** + * @brief acc ctrl2 register, offset:0x08 + */ + union + { + __IO uint32_t ctrl2; + struct + { + __IO uint32_t hickcal : 8; /* [7:0] */ + __IO uint32_t hicktrim : 6; /* [13:8] */ + __IO uint32_t reserved1 : 18;/* [31:14] */ + } ctrl2_bit; + }; + + /** + * @brief acc acc_c1 register, offset:0x0C + */ + union + { + __IO uint32_t c1; + struct + { + __IO uint32_t c1 : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } c1_bit; + }; + + /** + * @brief acc acc_c2 register, offset:0x10 + */ + union + { + __IO uint32_t c2; + struct + { + __IO uint32_t c2 : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } c2_bit; + }; + + /** + * @brief acc acc_c3 register, offset:0x14 + */ + union + { + __IO uint32_t c3; + struct + { + __IO uint32_t c3 : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } c3_bit; + }; +} acc_type; + +/** + * @} + */ + +#define ACC ((acc_type *) ACC_BASE) + +/** @defgroup ACC_exported_functions + * @{ + */ + +void acc_calibration_mode_enable(uint16_t acc_trim, confirm_state new_state); +void acc_step_set(uint8_t step_value); +void acc_interrupt_enable(uint16_t acc_int, confirm_state new_state); +uint8_t acc_hicktrim_get(void); +uint8_t acc_hickcal_get(void); +void acc_write_c1(uint16_t acc_c1_value); +void acc_write_c2(uint16_t acc_c2_value); +void acc_write_c3(uint16_t acc_c3_value); +uint16_t acc_read_c1(void); +uint16_t acc_read_c2(void); +uint16_t acc_read_c3(void); +flag_status acc_flag_get(uint16_t acc_flag); +flag_status acc_interrupt_flag_get(uint16_t acc_flag); +void acc_flag_clear(uint16_t acc_flag); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f403a_407_bpr.h b/libraries/drivers/inc/at32f403a_407_bpr.h new file mode 100644 index 0000000..08e15e3 --- /dev/null +++ b/libraries/drivers/inc/at32f403a_407_bpr.h @@ -0,0 +1,788 @@ +/** + ************************************************************************** + * @file at32f403a_407_bpr.h + * @brief at32f403a_407 bpr header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_BPR_H +#define __AT32F403A_407_BPR_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @addtogroup BPR + * @{ + */ + +/** @defgroup BPR_flags_definition + * @brief bpr flag + * @{ + */ + +#define BPR_TAMPER_INTERRUPT_FLAG ((uint32_t)0x00000001) /*!< bpr tamper interrupt flag */ +#define BPR_TAMPER_EVENT_FLAG ((uint32_t)0x00000002) /*!< bpr tamper event flag */ + +/** + * @} + */ + +/** @defgroup BPR_exported_types + * @{ + */ + +/** + * @brief battery powered register data type + */ +typedef enum +{ + BPR_DATA1 = 0x04, /*!< bpr data register 1 */ + BPR_DATA2 = 0x08, /*!< bpr data register 2 */ + BPR_DATA3 = 0x0C, /*!< bpr data register 3 */ + BPR_DATA4 = 0x10, /*!< bpr data register 4 */ + BPR_DATA5 = 0x14, /*!< bpr data register 5 */ + BPR_DATA6 = 0x18, /*!< bpr data register 6 */ + BPR_DATA7 = 0x1C, /*!< bpr data register 7 */ + BPR_DATA8 = 0x20, /*!< bpr data register 8 */ + BPR_DATA9 = 0x24, /*!< bpr data register 9 */ + BPR_DATA10 = 0x28, /*!< bpr data register 10 */ + BPR_DATA11 = 0x40, /*!< bpr data register 11 */ + BPR_DATA12 = 0x44, /*!< bpr data register 12 */ + BPR_DATA13 = 0x48, /*!< bpr data register 13 */ + BPR_DATA14 = 0x4C, /*!< bpr data register 14 */ + BPR_DATA15 = 0x50, /*!< bpr data register 15 */ + BPR_DATA16 = 0x54, /*!< bpr data register 16 */ + BPR_DATA17 = 0x58, /*!< bpr data register 17 */ + BPR_DATA18 = 0x5C, /*!< bpr data register 18 */ + BPR_DATA19 = 0x60, /*!< bpr data register 19 */ + BPR_DATA20 = 0x64, /*!< bpr data register 20 */ + BPR_DATA21 = 0x68, /*!< bpr data register 21 */ + BPR_DATA22 = 0x6C, /*!< bpr data register 22 */ + BPR_DATA23 = 0x70, /*!< bpr data register 23 */ + BPR_DATA24 = 0x74, /*!< bpr data register 24 */ + BPR_DATA25 = 0x78, /*!< bpr data register 25 */ + BPR_DATA26 = 0x7C, /*!< bpr data register 26 */ + BPR_DATA27 = 0x80, /*!< bpr data register 27 */ + BPR_DATA28 = 0x84, /*!< bpr data register 28 */ + BPR_DATA29 = 0x88, /*!< bpr data register 29 */ + BPR_DATA30 = 0x8C, /*!< bpr data register 30 */ + BPR_DATA31 = 0x90, /*!< bpr data register 31 */ + BPR_DATA32 = 0x94, /*!< bpr data register 32 */ + BPR_DATA33 = 0x98, /*!< bpr data register 33 */ + BPR_DATA34 = 0x9C, /*!< bpr data register 34 */ + BPR_DATA35 = 0xA0, /*!< bpr data register 35 */ + BPR_DATA36 = 0xA4, /*!< bpr data register 36 */ + BPR_DATA37 = 0xA8, /*!< bpr data register 37 */ + BPR_DATA38 = 0xAC, /*!< bpr data register 38 */ + BPR_DATA39 = 0xB0, /*!< bpr data register 39 */ + BPR_DATA40 = 0xB4, /*!< bpr data register 40 */ + BPR_DATA41 = 0xB8, /*!< bpr data register 41 */ + BPR_DATA42 = 0xBC /*!< bpr data register 42 */ +} bpr_data_type; + +/** + * @brief bpr rtc output type + */ +typedef enum +{ + BPR_RTC_OUTPUT_NONE = 0x000, /*!< output disable */ + BPR_RTC_OUTPUT_CLOCK_CAL_BEFORE = 0x080, /*!< output clock before calibration */ + BPR_RTC_OUTPUT_ALARM = 0x100, /*!< output alarm event with pluse mode */ + BPR_RTC_OUTPUT_SECOND = 0x300, /*!< output second event with pluse mode */ + BPR_RTC_OUTPUT_CLOCK_CAL_AFTER = 0x480, /*!< output clock after calibration */ + BPR_RTC_OUTPUT_ALARM_TOGGLE = 0x900, /*!< output alarm event with toggle mode */ + BPR_RTC_OUTPUT_SECOND_TOGGLE = 0xB00 /*!< output second event with toggle mode */ +} bpr_rtc_output_type; + +/** + * @brief tamper pin active level type + */ +typedef enum +{ + BPR_TAMPER_PIN_ACTIVE_HIGH = 0x00, /*!< tamper pin input active level is high */ + BPR_TAMPER_PIN_ACTIVE_LOW = 0x01 /*!< tamper pin input active level is low */ +} bpr_tamper_pin_active_level_type; + +/** + * @brief type define bpr register all + */ +typedef struct +{ + /** + * @brief reserved, offset:0x00 + */ + __IO uint32_t reserved1; + + /** + * @brief bpr dt1 register, offset:0x04 + */ + union + { + __IO uint32_t dt1; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt1_bit; + }; + + /** + * @brief bpr dt2 register, offset:0x08 + */ + union + { + __IO uint32_t dt2; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt2_bit; + }; + + /** + * @brief bpr dt3 register, offset:0x0C + */ + union + { + __IO uint32_t dt3; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt3_bit; + }; + + /** + * @brief bpr dt4 register, offset:0x10 + */ + union + { + __IO uint32_t dt4; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt4_bit; + }; + + /** + * @brief bpr dt5 register, offset:0x14 + */ + union + { + __IO uint32_t dt5; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt5_bit; + }; + + /** + * @brief bpr dt6 register, offset:0x18 + */ + union + { + __IO uint32_t dt6; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt6_bit; + }; + + /** + * @brief bpr dt7 register, offset:0x1C + */ + union + { + __IO uint32_t dt7; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt7_bit; + }; + + /** + * @brief bpr dt8 register, offset:0x20 + */ + union + { + __IO uint32_t dt8; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt8_bit; + }; + + /** + * @brief bpr dt9 register, offset:0x24 + */ + union + { + __IO uint32_t dt9; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt9_bit; + }; + + /** + * @brief bpr dt10 register, offset:0x28 + */ + union + { + __IO uint32_t dt10; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt10_bit; + }; + + /** + * @brief bpr rtccal register, offset:0x2C + */ + union + { + __IO uint32_t rtccal; + struct + { + __IO uint32_t calval : 7; /* [6:0] */ + __IO uint32_t calout : 1; /* [7] */ + __IO uint32_t outen : 1; /* [8] */ + __IO uint32_t outsel : 1; /* [9] */ + __IO uint32_t ccos : 1; /* [10] */ + __IO uint32_t outm : 1; /* [11] */ + __IO uint32_t reserved1 : 20;/* [31:12] */ + } rtccal_bit; + }; + + /** + * @brief bpr ctrl register, offset:0x30 + */ + union + { + __IO uint32_t ctrl; + struct + { + __IO uint32_t tpen : 1; /* [0] */ + __IO uint32_t tpp : 1; /* [1] */ + __IO uint32_t reserved1 : 30;/* [31:2] */ + } ctrl_bit; + }; + + /** + * @brief bpr ctrlsts register, offset:0x34 + */ + union + { + __IO uint32_t ctrlsts; + struct + { + __IO uint32_t tpefclr : 1;/* [0] */ + __IO uint32_t tpifclr : 1;/* [1] */ + __IO uint32_t tpien : 1;/* [2] */ + __IO uint32_t reserved1 : 5;/* [7:3] */ + __IO uint32_t tpef : 1;/* [8] */ + __IO uint32_t tpif : 1;/* [9] */ + __IO uint32_t reserved2 : 22;/* [31:10] */ + } ctrlsts_bit; + }; + + /** + * @brief reserved, offset:0x38 + */ + __IO uint32_t reserved2; + + /** + * @brief reserved, offset:0x3C + */ + __IO uint32_t reserved3; + + /** + * @brief bpr dt11 register, offset:0x40 + */ + union + { + __IO uint32_t dt11; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt11_bit; + }; + + /** + * @brief bpr dt12 register, offset:0x44 + */ + union + { + __IO uint32_t dt12; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt12_bit; + }; + + /** + * @brief bpr dt13 register, offset:0x48 + */ + union + { + __IO uint32_t dt13; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt13_bit; + }; + + /** + * @brief bpr dt14 register, offset:0x4C + */ + union + { + __IO uint32_t dt14; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt14_bit; + }; + + /** + * @brief bpr dt15 register, offset:0x50 + */ + union + { + __IO uint32_t dt15; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt15_bit; + }; + + /** + * @brief bpr dt16 register, offset:0x54 + */ + union + { + __IO uint32_t dt16; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt16_bit; + }; + + /** + * @brief bpr dt17 register, offset:0x58 + */ + union + { + __IO uint32_t dt17; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt17_bit; + }; + + /** + * @brief bpr dt18 register, offset:0x5C + */ + union + { + __IO uint32_t dt18; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt18_bit; + }; + + /** + * @brief bpr dt19 register, offset:0x60 + */ + union + { + __IO uint32_t dt19; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt19_bit; + }; + + /** + * @brief bpr dt20 register, offset:0x64 + */ + union + { + __IO uint32_t dt20; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt20_bit; + }; + + /** + * @brief bpr dt21 register, offset:0x68 + */ + union + { + __IO uint32_t dt21; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt21_bit; + }; + + /** + * @brief bpr dt22 register, offset:6C + */ + union + { + __IO uint32_t dt22; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt22_bit; + }; + + /** + * @brief bpr dt23 register, offset:0x70 + */ + union + { + __IO uint32_t dt23; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt23_bit; + }; + + /** + * @brief bpr dt24 register, offset:0x74 + */ + union + { + __IO uint32_t dt24; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt24_bit; + }; + + /** + * @brief bpr dt25 register, offset:0x78 + */ + union + { + __IO uint32_t dt25; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt25_bit; + }; + + /** + * @brief bpr dt26 register, offset:0x7C + */ + union + { + __IO uint32_t dt26; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt26_bit; + }; + + /** + * @brief bpr dt27 register, offset:0x80 + */ + union + { + __IO uint32_t dt27; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt27_bit; + }; + + /** + * @brief bpr dt28 register, offset:0x84 + */ + union + { + __IO uint32_t dt28; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt28_bit; + }; + + /** + * @brief bpr dt29 register, offset:0x88 + */ + union + { + __IO uint32_t dt29; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt29_bit; + }; + + /** + * @brief bpr dt30 register, offset:0x8C + */ + union + { + __IO uint32_t dt30; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt30_bit; + }; + + /** + * @brief bpr dt31 register, offset:0x90 + */ + union + { + __IO uint32_t dt31; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt31_bit; + }; + + /** + * @brief bpr dt32 register, offset:0x94 + */ + union + { + __IO uint32_t dt32; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt32_bit; + }; + + /** + * @brief bpr dt33 register, offset:0x98 + */ + union + { + __IO uint32_t dt33; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt33_bit; + }; + + /** + * @brief bpr dt34 register, offset:0x9C + */ + union + { + __IO uint32_t dt34; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt34_bit; + }; + + /** + * @brief bpr dt35 register, offset:0xA0 + */ + union + { + __IO uint32_t dt35; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt35_bit; + }; + + /** + * @brief bpr dt36 register, offset:0xA4 + */ + union + { + __IO uint32_t dt36; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt36_bit; + }; + + /** + * @brief bpr dt37 register, offset:0xA8 + */ + union + { + __IO uint32_t dt37; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt37_bit; + }; + + /** + * @brief bpr dt38 register, offset:0xAC + */ + union + { + __IO uint32_t dt38; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt38_bit; + }; + + /** + * @brief bpr dt39 register, offset:0xB0 + */ + union + { + __IO uint32_t dt39; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt39_bit; + }; + + /** + * @brief bpr dt40 register, offset:0xB4 + */ + union + { + __IO uint32_t dt40; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt40_bit; + }; + + /** + * @brief bpr dt41 register, offset:0xB8 + */ + union + { + __IO uint32_t dt41; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt41_bit; + }; + + /** + * @brief bpr dt42 register, offset:0xBC + */ + union + { + __IO uint32_t dt42; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt42_bit; + }; +} bpr_type; + +/** + * @} + */ + +#define BPR ((bpr_type *) BPR_BASE) + +/** @defgroup BPR_exported_functions + * @{ + */ + +void bpr_reset(void); +flag_status bpr_flag_get(uint32_t flag); +flag_status bpr_interrupt_flag_get(uint32_t flag); +void bpr_flag_clear(uint32_t flag); +void bpr_interrupt_enable(confirm_state new_state); +uint16_t bpr_data_read(bpr_data_type bpr_data); +void bpr_data_write(bpr_data_type bpr_data, uint16_t data_value); +void bpr_rtc_output_select(bpr_rtc_output_type output_source); +void bpr_rtc_clock_calibration_value_set(uint8_t calibration_value); +void bpr_tamper_pin_enable(confirm_state new_state); +void bpr_tamper_pin_active_level_set(bpr_tamper_pin_active_level_type active_level); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f403a_407_crc.h b/libraries/drivers/inc/at32f403a_407_crc.h new file mode 100644 index 0000000..375769d --- /dev/null +++ b/libraries/drivers/inc/at32f403a_407_crc.h @@ -0,0 +1,198 @@ +/** + ************************************************************************** + * @file at32f403a_407_crc.h + * @brief at32f403a_407 crc header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_CRC_H +#define __AT32F403A_407_CRC_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @addtogroup CRC + * @{ + */ + +/** @defgroup CRC_exported_types + * @{ + */ + +/** + * @brief crc reverse input data + */ +typedef enum +{ + CRC_REVERSE_INPUT_NO_AFFECTE = 0x00, /*!< input data no reverse */ + CRC_REVERSE_INPUT_BY_BYTE = 0x01, /*!< input data reverse by byte */ + CRC_REVERSE_INPUT_BY_HALFWORD = 0x02, /*!< input data reverse by half word */ + CRC_REVERSE_INPUT_BY_WORD = 0x03 /*!< input data reverse by word */ +} crc_reverse_input_type; + +/** + * @brief crc reverse output data + */ +typedef enum +{ + CRC_REVERSE_OUTPUT_NO_AFFECTE = 0x00, /*!< output data no reverse */ + CRC_REVERSE_OUTPUT_DATA = 0x01 /*!< output data reverse by word */ +} crc_reverse_output_type; + +/** + * @brief crc polynomial size + */ +typedef enum +{ + CRC_POLY_SIZE_32B = 0x00, /*!< polynomial size 32 bits */ + CRC_POLY_SIZE_16B = 0x01, /*!< polynomial size 16 bits */ + CRC_POLY_SIZE_8B = 0x02, /*!< polynomial size 8 bits */ + CRC_POLY_SIZE_7B = 0x03 /*!< polynomial size 7 bits */ +} crc_poly_size_type; + +/** + * @brief type define crc register all + */ +typedef struct +{ + /** + * @brief crc dt register, offset:0x00 + */ + union + { + __IO uint32_t dt; + struct + { + __IO uint32_t dt : 32; /* [31:0] */ + } dt_bit; + }; + + /** + * @brief crc cdt register, offset:0x04 + */ + union + { + __IO uint32_t cdt; + struct + { + __IO uint32_t cdt : 8 ; /* [7:0] */ + __IO uint32_t reserved1 : 24 ;/* [31:8] */ + } cdt_bit; + }; + + /** + * @brief crc ctrl register, offset:0x08 + */ + union + { + __IO uint32_t ctrl; + struct + { + __IO uint32_t rst : 1 ; /* [0] */ + __IO uint32_t reserved1 : 2 ; /* [2:1] */ + __IO uint32_t poly_size : 2 ; /* [4:3] */ + __IO uint32_t revid : 2 ; /* [6:5] */ + __IO uint32_t revod : 1 ; /* [7] */ + __IO uint32_t reserved2 : 24 ;/* [31:8] */ + } ctrl_bit; + }; + + /** + * @brief crm reserved1 register, offset:0x0C + */ + __IO uint32_t reserved1; + + /** + * @brief crc idt register, offset:0x10 + */ + union + { + __IO uint32_t idt; + struct + { + __IO uint32_t idt : 32; /* [31:0] */ + } idt_bit; + }; + + /** + * @brief crc polynomial register, offset:0x14 + */ + union + { + __IO uint32_t poly; + struct + { + __IO uint32_t poly : 32; /* [31:0] */ + } poly_bit; + }; + +} crc_type; + +/** + * @} + */ + +#define CRC ((crc_type *) CRC_BASE) + +/** @defgroup CRC_exported_functions + * @{ + */ + +void crc_data_reset(void); +uint32_t crc_one_word_calculate(uint32_t data); +uint32_t crc_block_calculate(uint32_t *pbuffer, uint32_t length); +uint32_t crc_data_get(void); +void crc_common_data_set(uint8_t cdt_value); +uint8_t crc_common_data_get(void); +void crc_init_data_set(uint32_t value); +void crc_reverse_input_data_set(crc_reverse_input_type value); +void crc_reverse_output_data_set(crc_reverse_output_type value); +void crc_poly_value_set(uint32_t value); +uint32_t crc_poly_value_get(void); +void crc_poly_size_set(crc_poly_size_type size); +crc_poly_size_type crc_poly_size_get(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f403a_407_dac.h b/libraries/drivers/inc/at32f403a_407_dac.h new file mode 100644 index 0000000..94e6051 --- /dev/null +++ b/libraries/drivers/inc/at32f403a_407_dac.h @@ -0,0 +1,372 @@ +/** + ************************************************************************** + * @file at32f403a_407_dac.h + * @brief at32f403a_407 dac header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_DAC_H +#define __AT32F403A_407_DAC_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @addtogroup DAC + * @{ + */ + +#define DAC1_D1DMAUDRF ((uint32_t)(0x00002000)) +#define DAC2_D2DMAUDRF ((uint32_t)(0x20000000)) + +/** @defgroup DAC_exported_types + * @{ + */ + +/** + * @brief dac select type + */ +typedef enum +{ + DAC1_SELECT = 0x01, /*!< dac1 select */ + DAC2_SELECT = 0x02 /*!< dac2 select */ +} dac_select_type; + +/** + * @brief dac trigger type + */ +typedef enum +{ + DAC_TMR6_TRGOUT_EVENT = 0x00, /*!< dac trigger selection:timer6 trgout event */ + DAC_TMR8_TRGOUT_EVENT = 0x01, /*!< dac trigger selection:timer8 trgout event */ + DAC_TMR7_TRGOUT_EVENT = 0x02, /*!< dac trigger selection:timer7 trgout event */ + DAC_TMR5_TRGOUT_EVENT = 0x03, /*!< dac trigger selection:timer5 trgout event */ + DAC_TMR2_TRGOUT_EVENT = 0x04, /*!< dac trigger selection:timer2 trgout event */ + DAC_TMR4_TRGOUT_EVENT = 0x05, /*!< dac trigger selection:timer4 trgout event */ + DAC_EXTERNAL_INTERRUPT_LINE_9 = 0x06, /*!< dac trigger selection:external line9 */ + DAC_SOFTWARE_TRIGGER = 0x07 /*!< dac trigger selection:software trigger */ +} dac_trigger_type; + +/** + * @brief dac wave type + */ +typedef enum +{ + DAC_WAVE_GENERATE_NONE = 0x00, /*!< dac wave generation disabled */ + DAC_WAVE_GENERATE_NOISE = 0x01, /*!< dac noise wave generation enabled */ + DAC_WAVE_GENERATE_TRIANGLE = 0x02 /*!< dac triangle wave generation enabled */ +} dac_wave_type; + +/** + * @brief dac mask amplitude type + */ +typedef enum +{ + DAC_LSFR_BIT0_AMPLITUDE_1 = 0x00, /*!< unmask bit0/ triangle amplitude equal to 1 */ + DAC_LSFR_BIT10_AMPLITUDE_3 = 0x01, /*!< unmask bit[1:0]/ triangle amplitude equal to 3 */ + DAC_LSFR_BIT20_AMPLITUDE_7 = 0x02, /*!< unmask bit[2:0]/ triangle amplitude equal to 7 */ + DAC_LSFR_BIT30_AMPLITUDE_15 = 0x03, /*!< unmask bit[3:0]/ triangle amplitude equal to 15 */ + DAC_LSFR_BIT40_AMPLITUDE_31 = 0x04, /*!< unmask bit[4:0]/ triangle amplitude equal to 31 */ + DAC_LSFR_BIT50_AMPLITUDE_63 = 0x05, /*!< unmask bit[5:0]/ triangle amplitude equal to 63 */ + DAC_LSFR_BIT60_AMPLITUDE_127 = 0x06, /*!< unmask bit[6:0]/ triangle amplitude equal to 127 */ + DAC_LSFR_BIT70_AMPLITUDE_255 = 0x07, /*!< unmask bit[7:0]/ triangle amplitude equal to 255 */ + DAC_LSFR_BIT80_AMPLITUDE_511 = 0x08, /*!< unmask bit[8:0]/ triangle amplitude equal to 511 */ + DAC_LSFR_BIT90_AMPLITUDE_1023 = 0x09, /*!< unmask bit[9:0]/ triangle amplitude equal to 1023 */ + DAC_LSFR_BITA0_AMPLITUDE_2047 = 0x0A, /*!< unmask bit[10:0]/ triangle amplitude equal to 2047 */ + DAC_LSFR_BITB0_AMPLITUDE_4095 = 0x0B /*!< unmask bit[11:0]/ triangle amplitude equal to 4095 */ +} dac_mask_amplitude_type; + +/** + * @brief dac1 aligned data type + */ +typedef enum +{ + DAC1_12BIT_RIGHT = 0x40007408, /*!< dac1 12-bit data right-aligned */ + DAC1_12BIT_LEFT = 0x4000740C, /*!< dac1 12-bit data left-aligned */ + DAC1_8BIT_RIGHT = 0x40007410 /*!< dac1 8-bit data right-aligned */ +} dac1_aligned_data_type; + +/** + * @brief dac2 aligned data type + */ +typedef enum +{ + DAC2_12BIT_RIGHT = 0x40007414, /*!< dac2 12-bit data right-aligned */ + DAC2_12BIT_LEFT = 0x40007418, /*!< dac2 12-bit data left-aligned */ + DAC2_8BIT_RIGHT = 0x4000741C /*!< dac2 8-bit data right-aligned */ +} dac2_aligned_data_type; + +/** + * @brief dac dual data type + */ +typedef enum +{ + DAC_DUAL_12BIT_RIGHT = 0x40007420, /*!ept[ept_num]) & USB_TX_MASK; \ + if((new_sts & USB_TXDTS0) != 0) \ + epsts ^= USB_TXDTS0; \ + if((new_sts & USB_TXDTS1) != 0) \ + epsts ^= USB_TXDTS1; \ + USB->ept[ept_num] = epsts | USB_RXTC | USB_TXTC; \ +} + +/** + * @brief set usb endpoint rx status + * @param ept_num: endpoint number + * @param new_sts: the new rx status of this endpoint number + * @retval none + */ +#define USB_SET_RXSTS(ept_num, new_sts) { \ + register uint16_t epsts = (USB->ept[ept_num]) & USB_RX_MASK; \ + if((new_sts & USB_RXDTS0) != 0) \ + epsts ^= USB_RXDTS0; \ + if((new_sts & USB_RXDTS1) != 0) \ + epsts ^= USB_RXDTS1; \ + USB->ept[ept_num] = epsts | USB_RXTC | USB_TXTC; \ +} + +/** + * @brief get usb endpoint tx/rx length address + * @param eptn: endpoint number + * @retval the length address of tx/rx + */ +#define GET_TX_LEN_ADDR(eptn) (uint32_t *)((USB->buftbl + eptn * 8 + 2) * 2 + g_usb_packet_address) +#define GET_RX_LEN_ADDR(eptn) (uint32_t *)((USB->buftbl + eptn * 8 + 6) * 2 + g_usb_packet_address) + +/** + * @brief get usb endpoint tx/rx data length + * @param eptn: endpoint number + * @retval the length of tx/rx + */ +#define USB_GET_TX_LEN(eptn) ((uint16_t)(*GET_TX_LEN_ADDR(eptn)) & 0x3ff) +#define USB_GET_RX_LEN(eptn) ((uint16_t)(*GET_RX_LEN_ADDR(eptn)) & 0x3ff) + +/** + * @brief double buffer mode get endpoint buf0/buf1 data length + * @param eptn: endpoint number + * @retval the length of buf0/buf1 + */ +#define USB_DBUF0_GET_LEN(eptn) USB_GET_TX_LEN(eptn) +#define USB_DBUF1_GET_LEN(eptn) USB_GET_RX_LEN(eptn) + +/** + * @brief set usb length of rx buffer + * @param reg: usb rx length register + * @param len: rx max length + * @param blks: number of blocks + */ +#define BLK32(reg, len, blks) { \ + blks = (len) >> 5; \ + if(((len) & 0x1F) == 0) \ + blks --; \ + *reg = ((uint16_t)((blks) << 10) | 0x8000); \ +} + +#define BLK2(reg, len, blks) { \ + blks = (len) >> 1; \ + if(((len) & 0x1) == 0) \ + blks ++; \ + *reg = (uint16_t)((blks) << 10); \ +} + +#define USB_SET_RXLEN_REG(reg, len) { \ + uint16_t blks; \ + if(len > 62) \ + { \ + BLK32(reg, len, blks); \ + } \ + else \ + { \ + BLK2(reg, len, blks); \ + } \ +} + +/** + * @brief set endpoint tx/rx transfer length + * @param eptn: endpoint number + * @param len: transfer length + * @retval none + */ +#define USB_SET_TXLEN(eptn, len) (*(GET_TX_LEN_ADDR(eptn)) = (len)) +#define USB_SET_RXLEN(eptn, len) { \ + uint32_t *rx_reg = GET_RX_LEN_ADDR(eptn); \ + USB_SET_RXLEN_REG(rx_reg, (len)); \ +} + +/** + * @brief double buffer mode set endpoint rx buf0 length + * @param eptn: endpoint number + * @param len: transfer length + * @retval none + */ +#define USB_OUT_EPT_DOUBLE_BUF0(eptn, len) { \ + uint32_t *rx_reg = GET_TX_LEN_ADDR(eptn); \ + USB_SET_RXLEN_REG(rx_reg, (len)); \ +} + +/** + * @brief double buffer mode set endpoint buf0 length + * @param eptn: endpoint number + * @param len: transfer length + * @param dir: transfer direction(in/out) + * @retval none + */ +#define USB_SET_EPT_DOUBLE_BUF0_LEN(eptn, len, dir) { \ + if(dir == DATA_TRANS_OUT) \ + { \ + USB_OUT_EPT_DOUBLE_BUF0(eptn, len); \ + } \ + else \ + { \ + *(GET_TX_LEN_ADDR(eptn)) = (len); \ + } \ +} + +/** + * @brief double buffer mode set endpoint buf1 length + * @param eptn: endpoint number + * @param len: transfer length + * @param dir: transfer direction(in/out) + * @retval none + */ +#define USB_SET_EPT_DOUBLE_BUF1_LEN(eptn, len, dir) { \ + if(dir == DATA_TRANS_OUT) \ + { \ + USB_SET_RXLEN(eptn, len); \ + } \ + else \ + { \ + *(GET_RX_LEN_ADDR(eptn)) = (len); \ + } \ +} + +/** + * @brief set usb endpoint tx/rx fifo address + * @param eptn: endpoint number + * @param address: offset of the fifo address + * @retval none + */ +#define USB_SET_TX_ADDRESS(eptn, address) (*(uint32_t *)((USB->buftbl + eptn * 8) * 2 + g_usb_packet_address) = address) +#define USB_SET_RX_ADDRESS(eptn, address) (*(uint32_t *)((USB->buftbl + eptn * 8 + 4) * 2 + g_usb_packet_address) = address) + +/** + * @brief set double buffer mode usb endpoint buf0/buf1 fifo address + * @param eptn: endpoint number + * @param address: offset of the fifo address + * @retval none + */ +#define USB_SET_DOUBLE_BUFF0_ADDRESS(eptn, address) (USB_SET_TX_ADDRESS(eptn, address)) +#define USB_SET_DOUBLE_BUFF1_ADDRESS(eptn, address) (USB_SET_RX_ADDRESS(eptn, address)) + +/** + * @brief set usb tx/rx toggle + * @param eptn: endpoint number + * @retval none + */ +#define USB_TOGGLE_TXDTS(eptn) (USB->ept[eptn] = ((USB->ept[eptn] & USB_EPT_BIT_MASK) | USB_TXDTS | USB_RXTC | USB_TXTC)) +#define USB_TOGGLE_RXDTS(eptn) (USB->ept[eptn] = ((USB->ept[eptn] & USB_EPT_BIT_MASK) | USB_RXDTS | USB_RXTC | USB_TXTC)) + +/** + * @brief clear usb tx/rx toggle + * @param eptn: endpoint number + * @retval none + */ +#define USB_CLEAR_TXDTS(eptn) { \ + if(USB->ept_bit[eptn].txdts != 0) \ + USB_TOGGLE_TXDTS(eptn); \ +} +#define USB_CLEAR_RXDTS(eptn) { \ + if(USB->ept_bit[eptn].rxdts != 0) \ + USB_TOGGLE_RXDTS(eptn); \ +} + +/** + * @brief set usb endpoint type + */ + +/** + * @brief set usb transfer type + * @param eptn: endpoint number + * @param type: transfer type + * @retval none + */ +#define USB_SET_TRANS_TYPE(eptn, type) (USB->ept[eptn] = (USB->ept[eptn] & USB_EPT_BIT_MASK & (~USB_TRANS_TYPE)) | type) + +/** + * @brief set/clear usb extend function + * @param eptn: endpoint number + * @retval none + */ +#define USB_SET_EXF(eptn) (USB->ept[eptn] = USB_TXTC | USB_RXTC | ((USB->ept[eptn] | USB_EXF) & USB_EPT_BIT_MASK)) +#define USB_CLEAR_EXF(eptn) (USB->ept[eptn] = USB_TXTC | USB_RXTC | (USB->ept[eptn] & ((~USB_EXF) & USB_EPT_BIT_MASK))) + +/** + * @brief set usb device address + * @param eptn: endpoint number + * @param address: device address + * @retval none + */ +#define USB_SET_EPT_ADDRESS(eptn, address) (USB->ept[eptn] = ((USB->ept[eptn] & USB_EPT_BIT_MASK & (~USB_EPTADDR)) | address)) + +/** + * @brief free buffer used by application + * @param eptn: endpoint number + * @param inout: transfer direction + * @retval none + */ +#define USB_FREE_DB_USER_BUFFER(eptn, inout) { \ + if(inout == DATA_TRANS_IN) \ + { \ + USB_TOGGLE_RXDTS(eptn); \ + } \ + else \ + { \ + USB_TOGGLE_TXDTS(eptn); \ + } \ +} + +/** + * @brief clear tx/rx transfer completed flag + * @param eptn: endpoint number + * @retval none + */ +#define USB_CLEAR_TXTC(eptn) (USB->ept[eptn] &= 0xFF7F & USB_EPT_BIT_MASK) +#define USB_CLEAR_RXTC(eptn) (USB->ept[eptn] &= 0x7FFF & USB_EPT_BIT_MASK) + +/** + * @brief set/clear endpoint double buffer mode + * @param eptn: endpoint number + * @retval none + */ +#define USB_SET_EPT_DOUBLE_BUFFER(eptn) USB_SET_EXF(eptn) +#define USB_CLEAR_EPT_DOUBLE_BUFFER(eptn) USB_CLEAR_EXF(eptn) + +/** + * @} + */ + +/** @defgroup USB_exported_types + * @{ + */ + +/** + * @brief usb endpoint infomation structure definition + */ +typedef struct +{ + uint8_t eptn; /*!< endpoint register number (0~7) */ + uint8_t ept_address; /*!< endpoint address */ + uint8_t inout; /*!< endpoint dir DATA_TRANS_IN or DATA_TRANS_OUT */ + uint8_t trans_type; /*!< endpoint type: + EPT_CONTROL_TYPE, EPT_BULK_TYPE, EPT_INT_TYPE, EPT_ISO_TYPE*/ + uint16_t tx_addr; /*!< endpoint tx buffer offset address */ + uint16_t rx_addr; /*!< endpoint rx buffer offset address */ + uint16_t maxpacket; /*!< endpoint max packet*/ + uint8_t is_double_buffer; /*!< endpoint double buffer flag */ + uint8_t stall; /*!< endpoint is stall state */ + uint16_t status; /*!< endpoint status */ + + /* transmission buffer and count */ + uint16_t total_len; /*!< endpoint transmission total length */ + uint16_t trans_len; /*!< endpoint transmission length*/ + uint8_t *trans_buf; /*!< endpoint transmission buffer */ + + uint16_t last_len; /*!< last transfer length */ + uint16_t rem0_len; /*!< rem transfer length */ + uint16_t ept0_slen; /*!< endpoint 0 transfer sum length */ +}usb_ept_info; + +/** + * @brief type define usb register all + */ +typedef struct +{ + /** + * @brief usb endpoint register, offset:0x00 + */ + union + { + __IO uint32_t ept[8]; + struct + { + __IO uint32_t eptaddr : 4; /* [3:0] */ + __IO uint32_t txsts : 2; /* [5:4] */ + __IO uint32_t txdts : 1; /* [6] */ + __IO uint32_t txtc : 1; /* [7] */ + __IO uint32_t exf : 1; /* [8] */ + __IO uint32_t trans_type : 2; /* [10:9] */ + __IO uint32_t setuptc : 1; /* [11] */ + __IO uint32_t rxsts : 2; /* [13:12] */ + __IO uint32_t rxdts : 1; /* [14] */ + __IO uint32_t rxtc : 1; /* [15] */ + __IO uint32_t reserved1 : 16; /* [31:16] */ + } ept_bit[8]; + }; + + __IO uint32_t reserved1[8]; + + /** + * @brief usb control register, offset:0x40 + */ + union + { + __IO uint32_t ctrl; + struct + { + __IO uint32_t csrst : 1; /* [0] */ + __IO uint32_t disusb : 1; /* [1] */ + __IO uint32_t lpm : 1; /* [2] */ + __IO uint32_t ssp : 1; /* [3] */ + __IO uint32_t gresume : 1; /* [4] */ + __IO uint32_t reserved1 : 3; /* [7:5] */ + __IO uint32_t lsofien : 1; /* [8] */ + __IO uint32_t sofien : 1; /* [9] */ + __IO uint32_t rstien : 1; /* [10] */ + __IO uint32_t spien : 1; /* [11] */ + __IO uint32_t wkien : 1; /* [12] */ + __IO uint32_t beien : 1; /* [13] */ + __IO uint32_t ucforien : 1; /* [14] */ + __IO uint32_t tcien : 1; /* [15] */ + __IO uint32_t reserved2 : 16; /* [31:16] */ + } ctrl_bit; + }; + + /** + * @brief usb interrupt status register, offset:0x44 + */ + union + { + __IO uint32_t intsts; + struct + { + __IO uint32_t ept_num : 4; /* [3:0] */ + __IO uint32_t inout : 1; /* [4] */ + __IO uint32_t reserved1 : 3; /* [7:5] */ + __IO uint32_t lsof : 1; /* [8] */ + __IO uint32_t sof : 1; /* [9] */ + __IO uint32_t rst : 1; /* [10] */ + __IO uint32_t sp : 1; /* [11] */ + __IO uint32_t wk : 1; /* [12] */ + __IO uint32_t be : 1; /* [13] */ + __IO uint32_t ucfor : 1; /* [14] */ + __IO uint32_t tc : 1; /* [15] */ + __IO uint32_t reserved2 : 16; /* [31:16] */ + } intsts_bit; + }; + + /** + * @brief usb frame number register, offset:0x48 + */ + union + { + __IO uint32_t sofrnum; + struct + { + __IO uint32_t sofnum : 11; /* [10:0] */ + __IO uint32_t lsofnum : 2; /* [12:11] */ + __IO uint32_t clck : 1; /* [13] */ + __IO uint32_t dmsts : 1; /* [14] */ + __IO uint32_t dpsts : 1; /* [15] */ + __IO uint32_t reserved1 : 16; /* [31:16] */ + } sofrnum_bit; + }; + + /** + * @brief usb device address register, offset:0x4c + */ + union + { + __IO uint32_t devaddr; + struct + { + __IO uint32_t addr : 7; /* [6:0] */ + __IO uint32_t cen : 1; /* [7] */ + __IO uint32_t reserved1 : 24; /* [31:8] */ + } devaddr_bit; + }; + + /** + * @brief usb buffer address register, offset:0x50 + */ + union + { + __IO uint32_t buftbl; + struct + { + __IO uint32_t reserved1 : 3; /* [2:0] */ + __IO uint32_t btaddr : 13; /* [15:3] */ + __IO uint32_t reserved2 : 16; /* [31:16] */ + } buftbl_bit; + }; + __IO uint32_t reserved2[3]; + /** + * @brief usb cfg control register, offset:0x60 + */ + union + { + __IO uint32_t cfg; + struct + { + __IO uint32_t sofouten : 1; /* [0] */ + __IO uint32_t puo : 1; /* [1] */ + __IO uint32_t reserved1 : 30; /* [31:2] */ + } cfg_bit; + }; + +} usbd_type; + +/** + * @} + */ + +#define USB ((usbd_type *) USBFS_BASE) + +typedef usbd_type usb_reg_type; +extern uint32_t g_usb_packet_address; + +/** @defgroup USB_exported_functions + * @{ + */ + +void usb_dev_init(usbd_type *usbx); +void usb_connect(usbd_type *usbx); +void usb_disconnect(usbd_type *usbx); +void usb_usbbufs_enable(usbd_type *usbx, confirm_state state); +void usb_ept_open(usbd_type *usbx, usb_ept_info *ept_info); +void usb_ept_close(usbd_type *usbx, usb_ept_info *ept_info); +void usb_write_packet(uint8_t *pusr_buf, uint16_t offset_addr, uint16_t nbytes); +void usb_read_packet(uint8_t *pusr_buf, uint16_t offset_addr, uint16_t nbytes); +void usb_interrupt_enable(usbd_type *usbx, uint16_t interrupt, confirm_state new_state); +void usb_set_address(usbd_type *usbx, uint8_t address); +void usb_ept_stall(usbd_type *usbx, usb_ept_info *ept_info); +void usb_enter_suspend(usbd_type *usbx); +void usb_exit_suspend(usbd_type *usbx); +void usb_remote_wkup_set(usbd_type *usbx); +void usb_remote_wkup_clear(usbd_type *usbx); +uint16_t usb_buffer_malloc(uint16_t maxpacket); +void usb_buffer_free(void); +flag_status usb_flag_get(usbd_type *usbx, uint16_t flag); +flag_status usb_interrupt_flag_get(usbd_type *usbx, uint16_t flag); +void usb_flag_clear(usbd_type *usbx, uint16_t flag); + + +#ifdef __cplusplus +} +#endif + +#endif +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/inc/at32f403a_407_wdt.h b/libraries/drivers/inc/at32f403a_407_wdt.h new file mode 100644 index 0000000..b581a56 --- /dev/null +++ b/libraries/drivers/inc/at32f403a_407_wdt.h @@ -0,0 +1,181 @@ +/** + ************************************************************************** + * @file at32f403a_407_wdt.h + * @brief at32f403a_407 wdt header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_WDT_H +#define __AT32F403A_407_WDT_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @addtogroup WDT + * @{ + */ + + +/** @defgroup WDT_flags_definition + * @brief wdt flag + * @{ + */ + +#define WDT_DIVF_UPDATE_FLAG ((uint16_t)0x0001) /*!< wdt division value update complete flag */ +#define WDT_RLDF_UPDATE_FLAG ((uint16_t)0x0002) /*!< wdt reload value update complete flag */ + +/** + * @} + */ + +/** @defgroup WDT_exported_types + * @{ + */ + +/** + * @brief wdt division value type + */ +typedef enum +{ + WDT_CLK_DIV_4 = 0x00, /*!< wdt clock divider value is 4 */ + WDT_CLK_DIV_8 = 0x01, /*!< wdt clock divider value is 8 */ + WDT_CLK_DIV_16 = 0x02, /*!< wdt clock divider value is 16 */ + WDT_CLK_DIV_32 = 0x03, /*!< wdt clock divider value is 32 */ + WDT_CLK_DIV_64 = 0x04, /*!< wdt clock divider value is 64 */ + WDT_CLK_DIV_128 = 0x05, /*!< wdt clock divider value is 128 */ + WDT_CLK_DIV_256 = 0x06 /*!< wdt clock divider value is 256 */ +} wdt_division_type; + +/** + * @brief wdt cmd value type + */ +typedef enum +{ + WDT_CMD_LOCK = 0x0000, /*!< disable write protection command */ + WDT_CMD_UNLOCK = 0x5555, /*!< enable write protection command */ + WDT_CMD_ENABLE = 0xCCCC, /*!< enable wdt command */ + WDT_CMD_RELOAD = 0xAAAA /*!< reload command */ +} wdt_cmd_value_type; + +/** + * @brief type define wdt register all + */ +typedef struct +{ + + /** + * @brief wdt cmd register, offset:0x00 + */ + union + { + __IO uint32_t cmd; + struct + { + __IO uint32_t cmd : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } cmd_bit; + }; + + /** + * @brief wdt div register, offset:0x04 + */ + union + { + __IO uint32_t div; + struct + { + __IO uint32_t div : 3; /* [2:0] */ + __IO uint32_t reserved1 : 29;/* [31:3] */ + } div_bit; + }; + + /** + * @brief wdt rld register, offset:0x08 + */ + union + { + __IO uint32_t rld; + struct + { + __IO uint32_t rld : 12;/* [11:0] */ + __IO uint32_t reserved1 : 20;/* [31:12] */ + } rld_bit; + }; + + /** + * @brief wdt sts register, offset:0x0C + */ + union + { + __IO uint32_t sts; + struct + { + __IO uint32_t divf : 1; /* [0] */ + __IO uint32_t rldf : 1; /* [1] */ + __IO uint32_t reserved1 : 30;/* [31:2] */ + } sts_bit; + }; + +} wdt_type; + +/** + * @} + */ + +#define WDT ((wdt_type *) WDT_BASE) + +/** @defgroup WDT_exported_functions + * @{ + */ + +void wdt_enable(void); +void wdt_counter_reload(void); +void wdt_reload_value_set(uint16_t reload_value); +void wdt_divider_set(wdt_division_type division); +void wdt_register_write_enable( confirm_state new_state); +flag_status wdt_flag_get(uint16_t wdt_flag); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f403a_407_wwdt.h b/libraries/drivers/inc/at32f403a_407_wwdt.h new file mode 100644 index 0000000..13a3023 --- /dev/null +++ b/libraries/drivers/inc/at32f403a_407_wwdt.h @@ -0,0 +1,157 @@ +/** + ************************************************************************** + * @file at32f403a_407_wwdt.h + * @brief at32f403a_407 wwdt header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_WWDT_H +#define __AT32F403A_407_WWDT_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @addtogroup WWDT + * @{ + */ + +/** @defgroup WWDT_enable_bit_definition + * @brief wwdt enable bit + * @{ + */ + +#define WWDT_EN_BIT ((uint32_t)0x00000080) /*!< wwdt enable bit */ + +/** + * @} + */ + +/** @defgroup WWDT_exported_types + * @{ + */ + +/** + * @brief wwdt division type + */ +typedef enum +{ + WWDT_PCLK1_DIV_4096 = 0x00, /*!< wwdt counter clock = (pclk1/4096)/1) */ + WWDT_PCLK1_DIV_8192 = 0x01, /*!< wwdt counter clock = (pclk1/4096)/2) */ + WWDT_PCLK1_DIV_16384 = 0x02, /*!< wwdt counter clock = (pclk1/4096)/4) */ + WWDT_PCLK1_DIV_32768 = 0x03 /*!< wwdt counter clock = (pclk1/4096)/8) */ +} wwdt_division_type; + +/** + * @brief type define wwdt register all + */ +typedef struct +{ + + /** + * @brief wwdt ctrl register, offset:0x00 + */ + union + { + __IO uint32_t ctrl; + struct + { + __IO uint32_t cnt : 7; /* [6:0] */ + __IO uint32_t wwdten : 1; /* [7] */ + __IO uint32_t reserved1 : 24;/* [31:8] */ + } ctrl_bit; + }; + + /** + * @brief wwdt cfg register, offset:0x04 + */ + union + { + __IO uint32_t cfg; + struct + { + __IO uint32_t win : 7; /* [6:0] */ + __IO uint32_t div : 2; /* [8:7] */ + __IO uint32_t rldien : 1; /* [9] */ + __IO uint32_t reserved1 : 22;/* [31:10] */ + } cfg_bit; + }; + + /** + * @brief wwdt cfg register, offset:0x08 + */ + union + { + __IO uint32_t sts; + struct + { + __IO uint32_t rldf : 1; /* [0] */ + __IO uint32_t reserved1 : 31;/* [31:1] */ + } sts_bit; + }; + +} wwdt_type; + +/** + * @} + */ + +#define WWDT ((wwdt_type *) WWDT_BASE) + +/** @defgroup WWDT_exported_functions + * @{ + */ + +void wwdt_reset(void); +void wwdt_divider_set(wwdt_division_type division); +void wwdt_flag_clear(void); +void wwdt_enable(uint8_t wwdt_cnt); +void wwdt_interrupt_enable(void); +flag_status wwdt_flag_get(void); +flag_status wwdt_interrupt_flag_get(void); +void wwdt_counter_set(uint8_t wwdt_cnt); +void wwdt_window_counter_set(uint8_t window_cnt); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f403a_407_xmc.h b/libraries/drivers/inc/at32f403a_407_xmc.h new file mode 100644 index 0000000..7f5c967 --- /dev/null +++ b/libraries/drivers/inc/at32f403a_407_xmc.h @@ -0,0 +1,567 @@ +/** + ************************************************************************** + * @file at32f403a_407_xmc.h + * @brief at32f403a_407 xmc header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_XMC_H +#define __AT32F403A_407_XMC_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @addtogroup XMC + * @{ + */ + +/** @defgroup XMC_exported_types + * @{ + */ + +/** + * @brief xmc data address bus multiplexing type + */ +typedef enum +{ + XMC_DATA_ADDR_MUX_DISABLE = 0x00000000, /*!< xmc address/data multiplexing disable */ + XMC_DATA_ADDR_MUX_ENABLE = 0x00000002 /*!< xmc address/data multiplexing enable */ +} xmc_data_addr_mux_type; + +/** + * @brief xmc burst access mode type + */ +typedef enum +{ + XMC_BURST_MODE_DISABLE = 0x00000000, /*!< xmc burst mode disable */ + XMC_BURST_MODE_ENABLE = 0x00000100 /*!< xmc burst mode enable */ +} xmc_burst_access_mode_type; + +/** + * @brief xmc asynchronous wait type + */ +typedef enum +{ + XMC_ASYN_WAIT_DISABLE = 0x00000000, /*!< xmc wait signal during asynchronous transfers disbale */ + XMC_ASYN_WAIT_ENABLE = 0x00008000 /*!< xmc wait signal during asynchronous transfers enable */ +} xmc_asyn_wait_type; + +/** + * @brief xmc wrapped mode type + */ +typedef enum +{ + XMC_WRAPPED_MODE_DISABLE = 0x00000000, /*!< xmc direct wrapped burst is disbale */ + XMC_WRAPPED_MODE_ENABLE = 0x00000400 /*!< xmc direct wrapped burst is enable */ +} xmc_wrap_mode_type; + +/** + * @brief xmc write operation type + */ +typedef enum +{ + XMC_WRITE_OPERATION_DISABLE = 0x00000000, /*!< xmc write operations is disable */ + XMC_WRITE_OPERATION_ENABLE = 0x00001000 /*!< xmc write operations is enable */ +} xmc_write_operation_type; + +/** + * @brief xmc wait signal type + */ +typedef enum +{ + XMC_WAIT_SIGNAL_DISABLE = 0x00000000, /*!< xmc nwait signal is disable */ + XMC_WAIT_SIGNAL_ENABLE = 0x00002000 /*!< xmc nwait signal is enable */ +} xmc_wait_signal_type; + +/** + * @brief xmc write burst type + */ +typedef enum +{ + XMC_WRITE_BURST_SYN_DISABLE = 0x00000000, /*!< xmc write operations are always performed in asynchronous mode */ + XMC_WRITE_BURST_SYN_ENABLE = 0x00080000 /*!< xmc write operations are performed in synchronous mode */ +} xmc_write_burst_type; + +/** + * @brief xmc extended mode type + */ +typedef enum +{ + XMC_WRITE_TIMING_DISABLE = 0x00000000, /*!< xmc write timing disable */ + XMC_WRITE_TIMING_ENABLE = 0x00004000 /*!< xmc write timing enable */ +} xmc_extended_mode_type; + +/** + * @brief xmc nand wait type + */ +typedef enum +{ + XMC_WAIT_OPERATION_DISABLE = 0x00000000, /*!< xmc wait operation for the nand flash memory bank disable */ + XMC_WAIT_OPERATION_ENABLE = 0x00000002 /*!< xmc wait operation for the nand flash memory bank enable */ +} xmc_nand_wait_type; + +/** + * @brief xmc ecc enable type + */ +typedef enum +{ + XMC_ECC_OPERATION_DISABLE = 0x00000000, /*!< xmc ecc module disable */ + XMC_ECC_OPERATION_ENABLE = 0x00000040 /*!< xmc ecc module enable */ +} xmc_ecc_enable_type; + +/** + * @brief xmc nor/sram bank type + */ +typedef enum +{ + XMC_BANK1_NOR_SRAM1 = 0x00000000, /*!< xmc nor/sram subbank1 */ + XMC_BANK1_NOR_SRAM4 = 0x00000003 /*!< xmc nor/sram subbank4 */ +} xmc_nor_sram_subbank_type; + +/** + * @brief xmc class bank type + */ +typedef enum +{ + XMC_BANK2_NAND = 0x00000010, /*!< xmc nand flash bank2 */ +} xmc_class_bank_type; + +/** + * @brief xmc memory type + */ +typedef enum +{ + XMC_DEVICE_SRAM = 0x00000000, /*!< xmc device choice sram */ + XMC_DEVICE_PSRAM = 0x00000004, /*!< xmc device choice psram */ + XMC_DEVICE_NOR = 0x00000008 /*!< xmc device choice nor flash */ +} xmc_memory_type; + +/** + * @brief xmc data width type + */ +typedef enum +{ + XMC_BUSTYPE_8_BITS = 0x00000000, /*!< xmc databuss width 8bits */ + XMC_BUSTYPE_16_BITS = 0x00000010 /*!< xmc databuss width 16bits */ +} xmc_data_width_type; + +/** + * @brief xmc wait signal polarity type + */ +typedef enum +{ + XMC_WAIT_SIGNAL_LEVEL_LOW = 0x00000000, /*!< xmc nwait active low */ + XMC_WAIT_SIGNAL_LEVEL_HIGH = 0x00000200 /*!< xmc nwait active high */ +} xmc_wait_signal_polarity_type; + +/** + * @brief xmc wait timing type + */ +typedef enum +{ + XMC_WAIT_SIGNAL_SYN_BEFORE = 0x00000000, /*!< xmc nwait signal is active one data cycle before wait state */ + XMC_WAIT_SIGNAL_SYN_DURING = 0x00000800 /*!< xmc nwait signal is active during wait state */ +} xmc_wait_timing_type; + +/** + * @brief xmc access mode type + */ +typedef enum +{ + XMC_ACCESS_MODE_A = 0x00000000, /*!< xmc access mode A */ + XMC_ACCESS_MODE_B = 0x10000000, /*!< xmc access mode B */ + XMC_ACCESS_MODE_C = 0x20000000, /*!< xmc access mode C */ + XMC_ACCESS_MODE_D = 0x30000000 /*!< xmc access mode D */ +} xmc_access_mode_type; + +/** + * @brief xmc ecc page size type + */ +typedef enum +{ + XMC_ECC_PAGESIZE_256_BYTES = 0x00000000, /*!< xmc ecc page size 256 bytes */ + XMC_ECC_PAGESIZE_512_BYTES = 0x00020000, /*!< xmc ecc page size 512 bytes */ + XMC_ECC_PAGESIZE_1024_BYTES = 0x00040000, /*!< xmc ecc page size 1024 bytes */ + XMC_ECC_PAGESIZE_2048_BYTES = 0x00060000, /*!< xmc ecc page size 2048 bytes */ + XMC_ECC_PAGESIZE_4096_BYTES = 0x00080000, /*!< xmc ecc page size 4096 bytes */ + XMC_ECC_PAGESIZE_8192_BYTES = 0x000A0000 /*!< xmc ecc page size 8192 bytes */ +} xmc_ecc_pagesize_type; + +/** + * @brief xmc interrupt sources type + */ +typedef enum +{ + XMC_INT_RISING_EDGE = 0x00000008, /*!< xmc rising edge detection interrupt enable */ + XMC_INT_LEVEL = 0x00000010, /*!< xmc high-level edge detection interrupt enable */ + XMC_INT_FALLING_EDGE = 0x00000020 /*!< xmc falling edge detection interrupt enable */ +} xmc_interrupt_sources_type; + +/** + * @brief xmc interrupt flag type + */ +typedef enum +{ + XMC_RISINGEDGE_FLAG = 0x00000001, /*!< xmc interrupt rising edge detection flag */ + XMC_LEVEL_FLAG = 0x00000002, /*!< xmc interrupt high-level edge detection flag */ + XMC_FALLINGEDGE_FLAG = 0x00000004, /*!< xmc interrupt falling edge detection flag */ + XMC_FEMPT_FLAG = 0x00000040 /*!< xmc fifo empty flag */ +} xmc_interrupt_flag_type; + +/** + * @brief nor/sram banks timing parameters + */ +typedef struct +{ + xmc_nor_sram_subbank_type subbank; /*!< xmc nor/sram subbank */ + xmc_extended_mode_type write_timing_enable; /*!< xmc nor/sram write timing enable */ + uint32_t addr_setup_time; /*!< xmc nor/sram address setup time */ + uint32_t addr_hold_time; /*!< xmc nor/sram address hold time */ + uint32_t data_setup_time; /*!< xmc nor/sram data setup time */ + uint32_t bus_latency_time; /*!< xmc nor/sram bus latency time */ + uint32_t clk_psc; /*!< xmc nor/sram clock prescale */ + uint32_t data_latency_time; /*!< xmc nor/sram data latency time */ + xmc_access_mode_type mode; /*!< xmc nor/sram access mode */ +} xmc_norsram_timing_init_type; + +/** + * @brief xmc nor/sram init structure definition + */ +typedef struct +{ + xmc_nor_sram_subbank_type subbank; /*!< xmc nor/sram subbank */ + xmc_data_addr_mux_type data_addr_multiplex; /*!< xmc nor/sram address/data multiplexing enable */ + xmc_memory_type device; /*!< xmc nor/sram memory device */ + xmc_data_width_type bus_type; /*!< xmc nor/sram data bus width */ + xmc_burst_access_mode_type burst_mode_enable; /*!< xmc nor/sram burst mode enable */ + xmc_asyn_wait_type asynwait_enable; /*!< xmc nor/sram nwait in asynchronous transfer enable */ + xmc_wait_signal_polarity_type wait_signal_lv; /*!< xmc nor/sram nwait polarity */ + xmc_wrap_mode_type wrapped_mode_enable; /*!< xmc nor/sram wrapped enable */ + xmc_wait_timing_type wait_signal_config; /*!< xmc nor/sram nwait timing configuration */ + xmc_write_operation_type write_enable; /*!< xmc nor/sram write enable */ + xmc_wait_signal_type wait_signal_enable; /*!< xmc nor/sram nwait in synchronous transfer enable */ + xmc_extended_mode_type write_timing_enable; /*!< xmc nor/sram read-write timing different */ + xmc_write_burst_type write_burst_syn; /*!< xmc nor/sram memory write mode control */ +} xmc_norsram_init_type; + +/** + * @brief nand timing parameters xmc + */ + +typedef struct +{ + xmc_class_bank_type class_bank; /*!< xmc nand bank */ + uint32_t mem_setup_time; /*!< xmc nand memory setup time */ + uint32_t mem_waite_time; /*!< xmc nand memory wait time */ + uint32_t mem_hold_time; /*!< xmc nand memory hold time */ + uint32_t mem_hiz_time; /*!< xmc nand memory databus high resistance time */ +} xmc_nand_timinginit_type; + +/** + * @brief xmc nand init structure definition + */ + +typedef struct +{ + xmc_class_bank_type nand_bank; /*!< xmc nand bank */ + xmc_nand_wait_type wait_enable; /*!< xmc wait feature enable */ + xmc_data_width_type bus_type; /*!< xmc nand bus width */ + xmc_ecc_enable_type ecc_enable; /*!< xmc nand ecc enable */ + xmc_ecc_pagesize_type ecc_pagesize; /*!< xmc nand ecc page size */ + uint32_t delay_time_cycle; /*!< xmc nand cle to re delay */ + uint32_t delay_time_ar; /*!< xmc nand ale to re delay */ +} xmc_nand_init_type; + +typedef struct +{ + /** + * @brief xmc bank1 bk1ctrl register, offset:0x00+0x08*(x-1) x= 1 or 4 + */ + union + { + __IO uint32_t bk1ctrl; + struct + { + __IO uint32_t en : 1; /* [0] */ + __IO uint32_t admuxen : 1; /* [1] */ + __IO uint32_t dev : 2; /* [3:2] */ + __IO uint32_t extmdbw : 2; /* [5:4] */ + __IO uint32_t noren : 1; /* [6] */ + __IO uint32_t reserved1 : 1; /* [7] */ + __IO uint32_t syncben : 1; /* [8] */ + __IO uint32_t nwpol : 1; /* [9] */ + __IO uint32_t wrapen : 1; /* [10] */ + __IO uint32_t nwtcfg : 1; /* [11] */ + __IO uint32_t wen : 1; /* [12] */ + __IO uint32_t nwsen : 1; /* [13] */ + __IO uint32_t rwtd : 1; /* [14] */ + __IO uint32_t nwasen : 1; /* [15] */ + __IO uint32_t crpgs : 3; /* [18:16] */ + __IO uint32_t mwmc : 1; /* [19] */ + __IO uint32_t reserved2 : 12;/* [31:20] */ + } bk1ctrl_bit; + }; + + /** + * @brief xmc bank1 bk1tmg register, offset:0x04+0x08*(x-1) x= 1 or 4 + */ + union + { + __IO uint32_t bk1tmg; + struct + { + __IO uint32_t addrst : 4; /* [3:0] */ + __IO uint32_t addrht : 4; /* [7:4] */ + __IO uint32_t dtst : 8; /* [15:8] */ + __IO uint32_t buslat : 4; /* [19:16] */ + __IO uint32_t clkpsc : 4; /* [23:20] */ + __IO uint32_t dtlat : 4; /* [27:24] */ + __IO uint32_t asyncm : 2; /* [29:28] */ + __IO uint32_t reserved1 : 2; /* [31:30] */ + } bk1tmg_bit; + }; + +} xmc_bank1_ctrl_tmg_reg_type; + +typedef struct +{ + /** + * @brief xmc bank1 bk1tmgwr register, offset:0x104+0x08*(x-1) x= 1 or 4 + */ + union + { + __IO uint32_t bk1tmgwr; + struct + { + __IO uint32_t addrst : 4; /* [3:0] */ + __IO uint32_t addrht : 4; /* [7:4] */ + __IO uint32_t dtst : 8; /* [15:8] */ + __IO uint32_t buslat : 4; /* [19:16] */ + __IO uint32_t reserved1 : 8; /* [27:20] */ + __IO uint32_t asyncm : 2; /* [29:28] */ + __IO uint32_t reserved2 : 2; /* [31:30] */ + } bk1tmgwr_bit; + }; + + /** + * @brief xmc bank1 reserved register + */ + __IO uint32_t reserved1; + +} xmc_bank1_tmgwr_reg_type; + +/** + * @brief xmc bank1 registers + */ +typedef struct +{ + /** + * @brief xmc bank1 ctrl and tmg register, offset:0x00~0x1C + */ + xmc_bank1_ctrl_tmg_reg_type ctrl_tmg_group[4]; + + /** + * @brief xmc bank1 reserved register, offset:0x20~0x100 + */ + __IO uint32_t reserved1[57]; + + /** + * @brief xmc bank1 tmgwr register, offset:0x104~0x11C + */ + xmc_bank1_tmgwr_reg_type tmgwr_group[4]; + + /** + * @brief xmc bank1 reserved register, offset:0x120~0x21C + */ + __IO uint32_t reserved2[63]; + + /** + * @brief xmc bank1 ext register, offset:0x220~0x22C + */ + union + { + __IO uint32_t ext[4]; + struct + { + __IO uint32_t buslatw2w : 8; /* [7:0] */ + __IO uint32_t buslatr2r : 8; /* [15:8] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } ext_bit[4]; + }; + +} xmc_bank1_type; + +/** + * @brief xmc bank2 registers + */ +typedef struct +{ + /** + * @brief xmc bk2ctrl register, offset:0x60 + */ + union + { + __IO uint32_t bk2ctrl; + struct + { + __IO uint32_t reserved1 : 1; /* [0] */ + __IO uint32_t nwen : 1; /* [1] */ + __IO uint32_t en : 1; /* [2] */ + __IO uint32_t dev : 1; /* [3] */ + __IO uint32_t extmdbw : 2; /* [5:4] */ + __IO uint32_t eccen : 1; /* [6] */ + __IO uint32_t reserved2 : 2; /* [8:7] */ + __IO uint32_t tcr : 4; /* [12:9] */ + __IO uint32_t tar : 4; /* [16:13] */ + __IO uint32_t eccpgs : 3; /* [19:17] */ + __IO uint32_t reserved3 : 12;/* [31:20] */ + } bk2ctrl_bit; + }; + + /** + * @brief xmc bk2is register, offset:0x64 + */ + union + { + __IO uint32_t bk2is; + struct + { + __IO uint32_t res : 1; /* [0] */ + __IO uint32_t hls : 1; /* [1] */ + __IO uint32_t fes : 1; /* [2] */ + __IO uint32_t reien : 1; /* [3] */ + __IO uint32_t hlien : 1; /* [4] */ + __IO uint32_t feien : 1; /* [5] */ + __IO uint32_t fifoe : 1; /* [6] */ + __IO uint32_t reserved1 : 25;/* [31:7] */ + } bk2is_bit; + }; + + /** + * @brief xmc bk2tmgmem register, offset:0x68 + */ + union + { + __IO uint32_t bk2tmgmem; + struct + { + __IO uint32_t cmst : 8; /* [7:0] */ + __IO uint32_t cmwt : 8; /* [15:8] */ + __IO uint32_t cmht : 8; /* [23:16] */ + __IO uint32_t cmdhizt : 8; /* [31:24] */ + } bk2tmgmem_bit; + }; + + /** + * @brief xmc bk2tmgatt register, offset:0x6C + */ + union + { + __IO uint32_t bk2tmgatt; + struct + { + __IO uint32_t amst : 8; /* [7:0] */ + __IO uint32_t amwt : 8; /* [15:8] */ + __IO uint32_t amht : 8; /* [23:16] */ + __IO uint32_t amdhizt : 8; /* [31:24] */ + } bk2tmgatt_bit; + }; + + /** + * @brief xmc reserved register, offset:0x70 + */ + __IO uint32_t reserved1; + + /** + * @brief xmc bk2ecc register, offset:0x74 + */ + union + { + __IO uint32_t bk2ecc; + struct + { + __IO uint32_t ecc : 32; /* [31:0] */ + } bk2ecc_bit; + }; + +} xmc_bank2_type; + +/** + * @} + */ + +#define XMC_BANK1 ((xmc_bank1_type *) XMC_BANK1_REG_BASE) +#define XMC_BANK2 ((xmc_bank2_type *) XMC_BANK2_REG_BASE) + +/** @defgroup XMC_exported_functions + * @{ + */ + +void xmc_nor_sram_reset(xmc_nor_sram_subbank_type xmc_subbank); +void xmc_nor_sram_init(xmc_norsram_init_type* xmc_norsram_init_struct); +void xmc_nor_sram_timing_config(xmc_norsram_timing_init_type* xmc_rw_timing_struct, + xmc_norsram_timing_init_type* xmc_w_timing_struct); +void xmc_norsram_default_para_init(xmc_norsram_init_type* xmc_nor_sram_init_struct); +void xmc_norsram_timing_default_para_init(xmc_norsram_timing_init_type* xmc_rw_timing_struct, + xmc_norsram_timing_init_type* xmc_w_timing_struct); +void xmc_nor_sram_enable(xmc_nor_sram_subbank_type xmc_subbank, confirm_state new_state); +void xmc_ext_timing_config(volatile xmc_nor_sram_subbank_type xmc_sub_bank, uint16_t w2w_timing, uint16_t r2r_timing); +void xmc_nand_reset(xmc_class_bank_type xmc_bank); +void xmc_nand_init(xmc_nand_init_type* xmc_nand_init_struct); +void xmc_nand_timing_config(xmc_nand_timinginit_type* xmc_common_spacetiming_struct, + xmc_nand_timinginit_type* xmc_attribute_spacetiming_struct); +void xmc_nand_default_para_init(xmc_nand_init_type* xmc_nand_init_struct); +void xmc_nand_timing_default_para_init(xmc_nand_timinginit_type* xmc_common_spacetiming_struct, + xmc_nand_timinginit_type* xmc_attribute_spacetiming_struct); +void xmc_nand_enable(xmc_class_bank_type xmc_bank, confirm_state new_state); +void xmc_nand_ecc_enable(xmc_class_bank_type xmc_bank, confirm_state new_state); +uint32_t xmc_ecc_get(xmc_class_bank_type xmc_bank); +void xmc_interrupt_enable(xmc_class_bank_type xmc_bank, xmc_interrupt_sources_type xmc_int, confirm_state new_state); +flag_status xmc_flag_status_get(xmc_class_bank_type xmc_bank, xmc_interrupt_flag_type xmc_flag); +flag_status xmc_interrupt_flag_status_get(xmc_class_bank_type xmc_bank, xmc_interrupt_flag_type xmc_flag); +void xmc_flag_clear(xmc_class_bank_type xmc_bank, xmc_interrupt_flag_type xmc_flag); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/src/at32f403a_407_acc.c b/libraries/drivers/src/at32f403a_407_acc.c new file mode 100644 index 0000000..50ff284 --- /dev/null +++ b/libraries/drivers/src/at32f403a_407_acc.c @@ -0,0 +1,232 @@ +/** + ************************************************************************** + * @file at32f403a_407_acc.c + * @brief contains all the functions for the acc firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup ACC + * @brief ACC driver modules + * @{ + */ + +#ifdef ACC_MODULE_ENABLED + +/** @defgroup ACC_private_functions + * @{ + */ + +/** + * @brief enable or disable the acc calibration mode. + * @param acc_trim: specifies the acc calibration type. + * this parameter can be one of the following values: + * - ACC_CAL_HICKCAL + * - ACC_CAL_HICKTRIM + * @param new_state: specifies the acc calibration to be enabled or disabled.(TRUE or FALSE) + * @retval none + */ +void acc_calibration_mode_enable(uint16_t acc_trim, confirm_state new_state) +{ + if(acc_trim == ACC_CAL_HICKCAL) + { + ACC->ctrl1_bit.entrim = FALSE; + } + else + { + ACC->ctrl1_bit.entrim = TRUE; + } + ACC->ctrl1_bit.calon = new_state; +} + +/** + * @brief store calibration step data in acc's ctrl1 register. + * @param step_value: value to be stored in the acc's ctrl1 register + * @retval none + */ +void acc_step_set(uint8_t step_value) +{ + ACC->ctrl1_bit.step = step_value; +} + +/** + * @brief enable or disable the specified acc interrupts. + * @param acc_int: specifies the acc interrupt sources to be enabled or disabled. + * this parameter can be one of the following values: + * - ACC_CALRDYIEN_INT + * - ACC_EIEN_INT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void acc_interrupt_enable(uint16_t acc_int, confirm_state new_state) +{ + if(acc_int == ACC_CALRDYIEN_INT) + { + ACC->ctrl1_bit.calrdyien = new_state; + } + else + { + ACC->ctrl1_bit.eien = new_state; + } +} + +/** + * @brief return the current acc hicktrim value. + * @param none + * @retval 8-bit hicktrim value. + */ +uint8_t acc_hicktrim_get(void) +{ + return ((uint8_t)(ACC->ctrl2_bit.hicktrim)); +} + +/** + * @brief return the current acc hickcal value. + * @param none + * @retval 8-bit hicktrim value. + */ +uint8_t acc_hickcal_get(void) +{ + return ((uint8_t)(ACC->ctrl2_bit.hickcal)); +} + +/** + * @brief wtire the value to acc c1 register. + * @param acc_c1_value + * @retval none. + */ +void acc_write_c1(uint16_t acc_c1_value) +{ + ACC->c1 = acc_c1_value; +} + +/** + * @brief wtire the value to acc c2 register. + * @param acc_c2_value + * @retval none. + */ +void acc_write_c2(uint16_t acc_c2_value) +{ + ACC->c2 = acc_c2_value; +} + +/** + * @brief wtire the value to acc c3 register. + * @param acc_c3_value + * @retval none. + */ +void acc_write_c3(uint16_t acc_c3_value) +{ + ACC->c3 = acc_c3_value; +} + +/** + * @brief return the current acc c1 value. + * @param none + * @retval 16-bit c1 value. + */ +uint16_t acc_read_c1(void) +{ + return ((uint16_t)(ACC->c1)); +} + +/** + * @brief return the current acc c2 value. + * @param none + * @retval 16-bit c2 value. + */ +uint16_t acc_read_c2(void) +{ + return ((uint16_t)(ACC->c2)); +} + +/** + * @brief return the current acc c3 value. + * @param none + * @retval 16-bit c3 value. + */ +uint16_t acc_read_c3(void) +{ + return ((uint16_t)(ACC->c3)); +} + +/** + * @brief check whether the specified acc flag is set or not. + * @param acc_flag: specifies the flag to check. + * this parameter can be one of the following values: + * - ACC_RSLOST_FLAG + * - ACC_CALRDY_FLAG + * @retval flag_status (SET or RESET) + */ +flag_status acc_flag_get(uint16_t acc_flag) +{ + if(acc_flag == ACC_CALRDY_FLAG) + return (flag_status)(ACC->sts_bit.calrdy); + else + return (flag_status)(ACC->sts_bit.rslost); +} + +/** + * @brief check whether the specified acc interrupt flag is set or not. + * @param acc_flag: specifies the flag to check. + * this parameter can be one of the following values: + * - ACC_RSLOST_FLAG + * - ACC_CALRDY_FLAG + * @retval flag_status (SET or RESET) + */ +flag_status acc_interrupt_flag_get(uint16_t acc_flag) +{ + if(acc_flag == ACC_CALRDY_FLAG) + return (flag_status)(ACC->sts_bit.calrdy && ACC->ctrl1_bit.calrdyien); + else + return (flag_status)(ACC->sts_bit.rslost && ACC->ctrl1_bit.eien); +} + +/** + * @brief clear the specified acc flag is set or not. + * @param acc_flag: specifies the flag to check. + * this parameter can be any combination of the following values: + * - ACC_RSLOST_FLAG + * - ACC_CALRDY_FLAG + * @retval none + */ +void acc_flag_clear(uint16_t acc_flag) +{ + ACC->sts = ~acc_flag; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f403a_407_bpr.c b/libraries/drivers/src/at32f403a_407_bpr.c new file mode 100644 index 0000000..82d77a5 --- /dev/null +++ b/libraries/drivers/src/at32f403a_407_bpr.c @@ -0,0 +1,224 @@ +/** + ************************************************************************** + * @file at32f403a_407_bpr.c + * @brief contains all the functions for the bpr firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup BPR + * @brief BPR driver modules + * @{ + */ + +#ifdef BPR_MODULE_ENABLED + +/** @defgroup BPR_private_functions + * @{ + */ + +/** + * @brief bpr reset by crm reset register + * @param none + * @retval none + */ +void bpr_reset(void) +{ + crm_battery_powered_domain_reset(TRUE); + crm_battery_powered_domain_reset(FALSE); +} + +/** + * @brief bpr event flag get, for tamper event flag + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - BPR_TAMPER_INTERRUPT_FLAG: tamper interrupt flag + * - BPR_TAMPER_EVENT_FLAG: tamper event flag + * @retval state of tamper event flag + */ +flag_status bpr_flag_get(uint32_t flag) +{ + if(flag == BPR_TAMPER_INTERRUPT_FLAG) + { + return (flag_status)(BPR->ctrlsts_bit.tpif); + } + else + { + return (flag_status)(BPR->ctrlsts_bit.tpef); + } +} + +/** + * @brief bpr interrupt flag get + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - BPR_TAMPER_INTERRUPT_FLAG: tamper interrupt flag + * - BPR_TAMPER_EVENT_FLAG: tamper event flag + * @retval state of tamper event flag + */ +flag_status bpr_interrupt_flag_get(uint32_t flag) +{ + if(flag == BPR_TAMPER_INTERRUPT_FLAG) + { + return (flag_status)(BPR->ctrlsts_bit.tpif && BPR->ctrlsts_bit.tpien); + } + else + { + return (flag_status)(BPR->ctrlsts_bit.tpef && BPR->ctrlsts_bit.tpien); + } +} + +/** + * @brief clear bpr tamper flag + * @param flag: specifies the flag to clear. + * this parameter can be one of the following values: + * - BPR_TAMPER_INTERRUPT_FLAG: tamper interrupt flag + * - BPR_TAMPER_EVENT_FLAG: tamper event flag + * @retval none + */ +void bpr_flag_clear(uint32_t flag) +{ + if(flag == BPR_TAMPER_INTERRUPT_FLAG) + { + BPR->ctrlsts_bit.tpifclr = TRUE; + } + else + { + BPR->ctrlsts_bit.tpefclr = TRUE; + } +} + +/** + * @brief enable or disable bpr tamper interrupt + * @param new_state (TRUE or FALSE) + * @retval none + */ +void bpr_interrupt_enable(confirm_state new_state) +{ + BPR->ctrlsts_bit.tpien = new_state; +} + +/** + * @brief read bpr bpr data + * @param bpr_data + * this parameter can be one of the following values: + * - BPR_DATA1 + * - BPR_DATA2 + * ... + * - BPR_DATA41 + * - BPR_DATA42 + * @retval none + */ +uint16_t bpr_data_read(bpr_data_type bpr_data) +{ + return (*(__IO uint16_t *)(BPR_BASE + bpr_data)); +} + +/** + * @brief write bpr data + * @param bpr_data + * this parameter can be one of the following values: + * - BPR_DATA1 + * - BPR_DATA2 + * ... + * - BPR_DATA41 + * - BPR_DATA42 + * @param data_value (0x0000~0xFFFF) + * @retval none + */ +void bpr_data_write(bpr_data_type bpr_data, uint16_t data_value) +{ + (*(__IO uint32_t *)(BPR_BASE + bpr_data)) = data_value; +} + +/** + * @brief select bpr rtc output + * @param output_source + * this parameter can be one of the following values: + * - BPR_RTC_OUTPUT_NONE: output disable. + * - BPR_RTC_OUTPUT_CLOCK_CAL_BEFORE: output clock before calibration. + * - BPR_RTC_OUTPUT_ALARM: output alarm event with pluse mode. + * - BPR_RTC_OUTPUT_SECOND: output second event with pluse mode. + * - BPR_RTC_OUTPUT_CLOCK_CAL_AFTER: output clock after calibration. + * - BPR_RTC_OUTPUT_ALARM_TOGGLE: output alarm event with toggle mode. + * - BPR_RTC_OUTPUT_SECOND_TOGGLE: output second event with toggle mode. + * @retval none + */ +void bpr_rtc_output_select(bpr_rtc_output_type output_source) +{ + /* clear cco,asoe,asos,ccos,togen bits */ + BPR->rtccal &= (uint32_t)~0x0F80; + + /* set output_source value */ + BPR->rtccal |= output_source; +} + +/** + * @brief set rtc clock calibration value + * @param calibration_value (0x00~0x7f) + * @retval none + */ +void bpr_rtc_clock_calibration_value_set(uint8_t calibration_value) +{ + /* set rtc clock calibration value */ + BPR->rtccal_bit.calval= calibration_value; +} + +/** + * @brief enable or disable bpr tamper pin + * @param new_state (TRUE or FALSE) + * @retval none + */ +void bpr_tamper_pin_enable(confirm_state new_state) +{ + BPR->ctrl_bit.tpen = new_state; +} + +/** + * @brief set bpr tamper pin active level + * @param active_level + * this parameter can be one of the following values: + * - BPR_TAMPER_PIN_ACTIVE_HIGH: tamper pin input active level is high. + * - BPR_TAMPER_PIN_ACTIVE_LOW: tamper pin input active level is low. + * @retval none + */ +void bpr_tamper_pin_active_level_set(bpr_tamper_pin_active_level_type active_level) +{ + BPR->ctrl_bit.tpp = active_level; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f403a_407_crc.c b/libraries/drivers/src/at32f403a_407_crc.c new file mode 100644 index 0000000..edd02a4 --- /dev/null +++ b/libraries/drivers/src/at32f403a_407_crc.c @@ -0,0 +1,208 @@ +/** + ************************************************************************** + * @file at32f403a_407_crc.c + * @brief contains all the functions for the crc firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup CRC + * @brief CRC driver modules + * @{ + */ + +#ifdef CRC_MODULE_ENABLED + +/** @defgroup CRC_private_functions + * @{ + */ + +/** + * @brief reset the crc data register. + * @param none + * @retval none + */ +void crc_data_reset(void) +{ + /* reset crc generator */ + CRC->ctrl_bit.rst = 0x1; +} + +/** + * @brief compute the 32-bit crc of a given data word(32-bit). + * @param data: data word(32-bit) to compute its crc + * @retval 32-bit crc + */ +uint32_t crc_one_word_calculate(uint32_t data) +{ + CRC->dt = data; + return (CRC->dt); +} + +/** + * @brief compute the 32-bit crc of a given buffer of data word(32-bit). + * @param pbuffer: pointer to the buffer containing the data to be computed + * @param length: length of the buffer to be computed + * @retval 32-bit crc + */ +uint32_t crc_block_calculate(uint32_t *pbuffer, uint32_t length) +{ + uint32_t index = 0; + + for(index = 0; index < length; index++) + { + CRC->dt = pbuffer[index]; + } + + return (CRC->dt); +} + +/** + * @brief return the current crc value. + * @param none + * @retval 32-bit crc + */ +uint32_t crc_data_get(void) +{ + return (CRC->dt); +} + +/** + * @brief store a 8-bit data in the common data register. + * @param cdt_value: 8-bit value to be stored in the common data register + * @retval none + */ +void crc_common_data_set(uint8_t cdt_value) +{ + CRC->cdt_bit.cdt = cdt_value; +} + +/** + * @brief return the 8-bit data stored in the common data register + * @param none + * @retval 8-bit value of the common data register + */ +uint8_t crc_common_data_get(void) +{ + return (CRC->cdt_bit.cdt); +} + +/** + * @brief set the 32-bit initial data of crc + * @param value: initial data + * @retval none + */ +void crc_init_data_set(uint32_t value) +{ + CRC->idt = value; +} + +/** + * @brief control the reversal of the bit order in the input data + * @param value + * this parameter can be one of the following values: + * - CRC_REVERSE_INPUT_NO_AFFECTE + * - CRC_REVERSE_INPUT_BY_BYTE + * - CRC_REVERSE_INPUT_BY_HALFWORD + * - CRC_REVERSE_INPUT_BY_WORD + * @retval none. + */ +void crc_reverse_input_data_set(crc_reverse_input_type value) +{ + CRC->ctrl_bit.revid = value; +} + +/** + * @brief control the reversal of the bit order in the output data + * @param value + * this parameter can be one of the following values: + * - CRC_REVERSE_OUTPUT_NO_AFFECTE + * - CRC_REVERSE_OUTPUT_DATA + * @retval none. + */ +void crc_reverse_output_data_set(crc_reverse_output_type value) +{ + CRC->ctrl_bit.revod = value; +} + +/** + * @brief config crc polynomial value + * @param value + * 32-bit new data of crc poly value + * @retval none. + */ +void crc_poly_value_set(uint32_t value) +{ + CRC->poly = value; +} + +/** + * @brief return crc polynomial value + * @param none + * @retval 32-bit value of the polynomial value. + */ +uint32_t crc_poly_value_get(void) +{ + return (CRC->poly); +} + +/** + * @brief config crc polynomial data size + * @param size + * this parameter can be one of the following values: + * - CRC_POLY_SIZE_32B + * - CRC_POLY_SIZE_16B + * - CRC_POLY_SIZE_8B + * - CRC_POLY_SIZE_7B + * @retval none. + */ +void crc_poly_size_set(crc_poly_size_type size) +{ + CRC->ctrl_bit.poly_size = size; +} + +/** + * @brief return crc polynomial data size + * @param none + * @retval polynomial data size. + */ +crc_poly_size_type crc_poly_size_get(void) +{ + return (crc_poly_size_type)(CRC->ctrl_bit.poly_size); +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f403a_407_dac.c b/libraries/drivers/src/at32f403a_407_dac.c new file mode 100644 index 0000000..5791e8e --- /dev/null +++ b/libraries/drivers/src/at32f403a_407_dac.c @@ -0,0 +1,378 @@ +/** + ************************************************************************** + * @file at32f403a_407_dac.c + * @brief contains all the functions for the dac firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup DAC + * @brief DAC driver modules + * @{ + */ + +#ifdef DAC_MODULE_ENABLED + +/** @defgroup DAC_private_functions + * @{ + */ + +/** + * @brief dac reset + * @param none + * @retval none + */ +void dac_reset(void) +{ + crm_periph_reset(CRM_DAC_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_DAC_PERIPH_RESET, FALSE); +} + +/** + * @brief enable or disable dac + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void dac_enable(dac_select_type dac_select, confirm_state new_state) +{ + switch(dac_select) + { + case DAC1_SELECT: + DAC->ctrl_bit.d1en = new_state; + break; + case DAC2_SELECT: + DAC->ctrl_bit.d2en = new_state; + break; + default: + break; + } +} + +/** + * @brief enable or disable dac output buffer + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void dac_output_buffer_enable(dac_select_type dac_select, confirm_state new_state) +{ + new_state = (confirm_state)!new_state; + switch(dac_select) + { + case DAC1_SELECT: + DAC->ctrl_bit.d1obdis = new_state; + break; + case DAC2_SELECT: + DAC->ctrl_bit.d2obdis = new_state; + break; + default: + break; + } +} + +/** + * @brief enable or disable dac trigger + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void dac_trigger_enable(dac_select_type dac_select, confirm_state new_state) +{ + switch(dac_select) + { + case DAC1_SELECT: + DAC->ctrl_bit.d1trgen = new_state; + break; + case DAC2_SELECT: + DAC->ctrl_bit.d2trgen = new_state; + break; + default: + break; + } +} + +/** + * @brief select dac trigger + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @param dac_trigger_source + * this parameter can be one of the following values: + * - DAC_TMR6_TRGOUT_EVENT + * - DAC_TMR8_TRGOUT_EVENT + * - DAC_TMR7_TRGOUT_EVENT + * - DAC_TMR5_TRGOUT_EVENT + * - DAC_TMR2_TRGOUT_EVENT + * - DAC_TMR4_TRGOUT_EVENT + * - DAC_EXTERNAL_INTERRUPT_LINE_9 + * - DAC_SOFTWARE_TRIGGER + * @retval none + */ +void dac_trigger_select(dac_select_type dac_select, dac_trigger_type dac_trigger_source) +{ + switch(dac_select) + { + case DAC1_SELECT: + DAC->ctrl_bit.d1trgsel = dac_trigger_source; + break; + case DAC2_SELECT: + DAC->ctrl_bit.d2trgsel = dac_trigger_source; + break; + default: + break; + } +} + +/** + * @brief generate dac software trigger + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @retval none + */ +void dac_software_trigger_generate(dac_select_type dac_select) +{ + switch(dac_select) + { + case DAC1_SELECT: + DAC->swtrg_bit.d1swtrg = TRUE; + break; + case DAC2_SELECT: + DAC->swtrg_bit.d2swtrg = TRUE; + break; + default: + break; + } +} + +/** + * @brief generate dac dual software trigger synchronously + * @param none + * @retval none + */ +void dac_dual_software_trigger_generate(void) +{ + DAC->swtrg |= 0x03; +} + +/** + * @brief generate dac wave + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @param dac_wave + * this parameter can be one of the following values: + * - DAC_WAVE_GENERATE_NONE + * - DAC_WAVE_GENERATE_NOISE + * - DAC_WAVE_GENERATE_TRIANGLE + * @retval none + */ +void dac_wave_generate(dac_select_type dac_select, dac_wave_type dac_wave) +{ + switch(dac_select) + { + case DAC1_SELECT: + DAC->ctrl_bit.d1nm = dac_wave; + break; + case DAC2_SELECT: + DAC->ctrl_bit.d2nm = dac_wave; + break; + default: + break; + } +} + +/** + * @brief select dac mask amplitude + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @param dac_mask_amplitude + * this parameter can be one of the following values: + * - DAC_LSFR_BIT0_AMPLITUDE_1 + * - DAC_LSFR_BIT10_AMPLITUDE_3 + * - DAC_LSFR_BIT20_AMPLITUDE_7 + * - DAC_LSFR_BIT30_AMPLITUDE_15 + * - DAC_LSFR_BIT40_AMPLITUDE_31 + * - DAC_LSFR_BIT50_AMPLITUDE_63 + * - DAC_LSFR_BIT60_AMPLITUDE_127 + * - DAC_LSFR_BIT70_AMPLITUDE_255 + * - DAC_LSFR_BIT80_AMPLITUDE_511 + * - DAC_LSFR_BIT90_AMPLITUDE_1023 + * - DAC_LSFR_BITA0_AMPLITUDE_2047 + * - DAC_LSFR_BITB0_AMPLITUDE_4095 + * @retval none + */ +void dac_mask_amplitude_select(dac_select_type dac_select, dac_mask_amplitude_type dac_mask_amplitude) +{ + switch(dac_select) + { + case DAC1_SELECT: + DAC->ctrl_bit.d1nbsel = dac_mask_amplitude; + break; + case DAC2_SELECT: + DAC->ctrl_bit.d2nbsel = dac_mask_amplitude; + break; + default: + break; + } +} + +/** + * @brief enable or disable dac dma + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void dac_dma_enable(dac_select_type dac_select, confirm_state new_state) +{ + switch(dac_select) + { + case DAC1_SELECT: + DAC->ctrl_bit.d1dmaen = new_state; + break; + case DAC2_SELECT: + DAC->ctrl_bit.d2dmaen = new_state; + break; + default: + break; + } +} + +/** + * @brief get dac data output + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @retval dac channel data output + */ +uint16_t dac_data_output_get(dac_select_type dac_select) +{ + uint16_t data_output =0 ; + switch(dac_select) + { + case DAC1_SELECT: + data_output = DAC->d1odt_bit.d1odt; + break; + case DAC2_SELECT: + data_output = DAC->d2odt_bit.d2odt; + break; + default: + break; + } + return data_output; +} + +/** + * @brief set dac1 data + * @param dac1_aligned + * this parameter can be one of the following values: + * DAC1_12BIT_RIGHT + * DAC1_12BIT_LEFT + * DAC1_8BIT_RIGHT + * @param dac1_data :indecate from selected data holding register + * @retval none + */ +void dac_1_data_set(dac1_aligned_data_type dac1_aligned, uint16_t dac1_data) +{ + *(__IO uint32_t *) dac1_aligned = dac1_data; +} + +/** + * @brief set dac2 data + * @param dac2_aligned + * this parameter can be one of the following values: + * DAC2_12BIT_RIGHT + * DAC2_12BIT_LEFT + * DAC2_8BIT_RIGHT + * @param dac2_data :indecate from selected data holding register + * @retval none + */ +void dac_2_data_set(dac2_aligned_data_type dac2_aligned, uint16_t dac2_data) +{ + *(__IO uint32_t *) dac2_aligned = dac2_data; +} + +/** + * @brief set dac dual data + * @param dac_dual + * this parameter can be one of the following values: + * DAC_DUAL_12BIT_RIGHT + * DAC_DUAL_12BIT_LEFT + * DAC_DUAL_8BIT_RIGHT + * @param data1 :dac1 channel indecate from selected data holding register + * @param data2 :dac1 channel indecate from selected data holding register + * @retval none + */ +void dac_dual_data_set(dac_dual_data_type dac_dual, uint16_t data1, uint16_t data2) +{ + switch(dac_dual) + { + case DAC_DUAL_12BIT_RIGHT: + *(__IO uint32_t *) dac_dual = (uint32_t)(data1 | (data2 << 16)); + break; + case DAC_DUAL_12BIT_LEFT: + *(__IO uint32_t *) dac_dual = (uint32_t)(data1 | (data2 << 16)); + break; + case DAC_DUAL_8BIT_RIGHT: + *(__IO uint32_t *) dac_dual = (uint32_t)(data1 | (data2 << 8)); + break; + default: + break; + } +} + + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f403a_407_dma.c b/libraries/drivers/src/at32f403a_407_dma.c new file mode 100644 index 0000000..ab2d16d --- /dev/null +++ b/libraries/drivers/src/at32f403a_407_dma.c @@ -0,0 +1,475 @@ +/** + ************************************************************************** + * @file at32f403a_407_dma.c + * @brief contains all the functions for the dma firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup DMA + * @brief DMA driver modules + * @{ + */ + +#ifdef DMA_MODULE_ENABLED + +/** @defgroup DMA_private_functions + * @{ + */ + +/** + * @brief reset the dmax channely registers. + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * - DMA2_CHANNEL1 + * - DMA2_CHANNEL2 + * - DMA2_CHANNEL3 + * - DMA2_CHANNEL4 + * - DMA2_CHANNEL5 + * - DMA2_CHANNEL6 + * - DMA2_CHANNEL7 + * @retval none + */ +void dma_reset(dma_channel_type* dmax_channely) +{ + uint32_t temp = 0; + dmax_channely->ctrl_bit.chen = FALSE; + dmax_channely->ctrl = 0; + dmax_channely->dtcnt = 0; + dmax_channely->paddr = 0; + dmax_channely->maddr = 0; + + temp = (uint32_t)dmax_channely; + + if((temp & 0x4ff) < 0x408) + { + /* dma1 channel */ + DMA1->clr |= (uint32_t)(0x0f << ((((temp & 0xff) - 0x08) / 0x14) * 4)); + } + else if((temp & 0x4ff) < 0x488) + { + /* dma2 channel */ + DMA2->clr |= (uint32_t)(0x0f << ((((temp & 0xff) - 0x08) / 0x14) * 4)); + } +} + +/** + * @brief set the number of data to be transferred + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * - DMA2_CHANNEL1 + * - DMA2_CHANNEL2 + * - DMA2_CHANNEL3 + * - DMA2_CHANNEL4 + * - DMA2_CHANNEL5 + * - DMA2_CHANNEL6 + * - DMA2_CHANNEL7 + * @param data_number: the number of data to be transferred(0x0000~0xFFFF) + * transfer. + * @retval none. + */ +void dma_data_number_set(dma_channel_type* dmax_channely, uint16_t data_number) +{ + dmax_channely->dtcnt = data_number; +} + +/** + * @brief get number of data from dtcnt register + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * - DMA2_CHANNEL1 + * - DMA2_CHANNEL2 + * - DMA2_CHANNEL3 + * - DMA2_CHANNEL4 + * - DMA2_CHANNEL5 + * - DMA2_CHANNEL6 + * - DMA2_CHANNEL7 + * @retval the number of data. + */ +uint16_t dma_data_number_get(dma_channel_type* dmax_channely) +{ + return (uint16_t)dmax_channely->dtcnt; +} + +/** + * @brief enable or disable dma interrupt + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * - DMA2_CHANNEL1 + * - DMA2_CHANNEL2 + * - DMA2_CHANNEL3 + * - DMA2_CHANNEL4 + * - DMA2_CHANNEL5 + * - DMA2_CHANNEL6 + * - DMA2_CHANNEL7 + * @param dma_int: + * this parameter can be any combination of the following values: + * - DMA_FDT_INT + * - DMA_HDT_INT + * - DMA_DTERR_INT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void dma_interrupt_enable(dma_channel_type* dmax_channely, uint32_t dma_int, confirm_state new_state) +{ + if (new_state != FALSE) + { + dmax_channely->ctrl |= dma_int; + } + else + { + dmax_channely->ctrl &= ~dma_int; + } +} + +/** + * @brief enable or disable dma channely + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * - DMA2_CHANNEL1 + * - DMA2_CHANNEL2 + * - DMA2_CHANNEL3 + * - DMA2_CHANNEL4 + * - DMA2_CHANNEL5 + * - DMA2_CHANNEL6 + * - DMA2_CHANNEL7 + * @param new_state (TRUE or FALSE) + * @retval None + */ +void dma_channel_enable(dma_channel_type* dmax_channely, confirm_state new_state) +{ + dmax_channely->ctrl_bit.chen = new_state; +} + +/** + * @brief initialize the dma_x flexible function according to the specified parameters. + * @param dma_x: + * this parameter can be one of the following values: + * - DMA1 + * - DMA2 + * @param flex_channelx: + * this parameter can be one of the following values: + * - FLEX_CHANNEL1 + * - FLEX_CHANNEL2 + * - FLEX_CHANNEL3 + * - FLEX_CHANNEL4 + * - FLEX_CHANNEL5 + * - FLEX_CHANNEL6 + * - FLEX_CHANNEL7 + * @param flexible_request: every peripheral have specified hardware_id. + * this parameter can be one of the following values: + * - DMA_FLEXIBLE_ADC1 - DMA_FLEXIBLE_ADC3 - DMA_FLEXIBLE_DAC1 - DMA_FLEXIBLE_DAC2 + * - DMA_FLEXIBLE_SPI1_RX - DMA_FLEXIBLE_SPI1_TX - DMA_FLEXIBLE_SPI2_RX - DMA_FLEXIBLE_SPI2_TX + * - DMA_FLEXIBLE_SPI3_RX - DMA_FLEXIBLE_SPI3_TX - DMA_FLEXIBLE_SPI4_RX - DMA_FLEXIBLE_SPI4_TX + * - DMA_FLEXIBLE_I2S2EXT_RX - DMA_FLEXIBLE_I2S2EXT_TX - DMA_FLEXIBLE_I2S3EXT_RX - DMA_FLEXIBLE_I2S3EXT_TX + * - DMA_FLEXIBLE_UART1_RX - DMA_FLEXIBLE_UART1_TX - DMA_FLEXIBLE_UART2_RX - DMA_FLEXIBLE_UART2_TX + * - DMA_FLEXIBLE_UART3_RX - DMA_FLEXIBLE_UART3_TX - DMA_FLEXIBLE_UART4_RX - DMA_FLEXIBLE_UART4_TX + * - DMA_FLEXIBLE_UART5_RX - DMA_FLEXIBLE_UART5_TX - DMA_FLEXIBLE_UART6_RX - DMA_FLEXIBLE_UART6_TX + * - DMA_FLEXIBLE_UART7_RX - DMA_FLEXIBLE_UART7_TX - DMA_FLEXIBLE_UART8_RX - DMA_FLEXIBLE_UART8_TX + * - DMA_FLEXIBLE_I2C1_RX - DMA_FLEXIBLE_I2C1_TX - DMA_FLEXIBLE_I2C2_RX - DMA_FLEXIBLE_I2C2_TX + * - DMA_FLEXIBLE_I2C3_RX - DMA_FLEXIBLE_I2C3_TX - DMA_FLEXIBLE_SDIO1 - DMA_FLEXIBLE_SDIO2 + * - DMA_FLEXIBLE_TMR1_TRIG - DMA_FLEXIBLE_TMR1_HALL - DMA_FLEXIBLE_TMR1_OVERFLOW- DMA_FLEXIBLE_TMR1_CH1 + * - DMA_FLEXIBLE_TMR1_CH2 - DMA_FLEXIBLE_TMR1_CH3 - DMA_FLEXIBLE_TMR1_CH4 - DMA_FLEXIBLE_TMR2_TRIG + * - DMA_FLEXIBLE_TMR2_OVERFLOW- DMA_FLEXIBLE_TMR2_CH1 - DMA_FLEXIBLE_TMR2_CH2 - DMA_FLEXIBLE_TMR2_CH3 + * - DMA_FLEXIBLE_TMR2_CH4 - DMA_FLEXIBLE_TMR3_TRIG - DMA_FLEXIBLE_TMR3_OVERFLOW- DMA_FLEXIBLE_TMR3_CH1 + * - DMA_FLEXIBLE_TMR3_CH2 - DMA_FLEXIBLE_TMR3_CH3 - DMA_FLEXIBLE_TMR3_CH4 - DMA_FLEXIBLE_TMR4_TRIG + * - DMA_FLEXIBLE_TMR4_OVERFLOW- DMA_FLEXIBLE_TMR4_CH1 - DMA_FLEXIBLE_TMR4_CH2 - DMA_FLEXIBLE_TMR4_CH3 + * - DMA_FLEXIBLE_TMR4_CH4 - DMA_FLEXIBLE_TMR5_TRIG - DMA_FLEXIBLE_TMR5_OVERFLOW- DMA_FLEXIBLE_TMR5_CH1 + * - DMA_FLEXIBLE_TMR5_CH2 - DMA_FLEXIBLE_TMR5_CH3 - DMA_FLEXIBLE_TMR5_CH4 - DMA_FLEXIBLE_TMR6_OVERFLOW + * - DMA_FLEXIBLE_TMR7_OVERFLOW- DMA_FLEXIBLE_TMR8_TRIG - DMA_FLEXIBLE_TMR8_HALL - DMA_FLEXIBLE_TMR8_OVERFLOW + * - DMA_FLEXIBLE_TMR8_CH1 - DMA_FLEXIBLE_TMR8_CH2 - DMA_FLEXIBLE_TMR8_CH3 - DMA_FLEXIBLE_TMR8_CH4 + * @retval none + */ + +void dma_flexible_config(dma_type* dma_x, uint8_t flex_channelx, dma_flexible_request_type flexible_request) +{ + if(dma_x->src_sel1_bit.dma_flex_en == RESET) + { + dma_x->src_sel1_bit.dma_flex_en = TRUE; + } + + if(flex_channelx == FLEX_CHANNEL1) + { + dma_x->src_sel0_bit.ch1_src = flexible_request; + } + else if(flex_channelx == FLEX_CHANNEL2) + { + dma_x->src_sel0_bit.ch2_src = flexible_request; + } + else if(flex_channelx == FLEX_CHANNEL3) + { + dma_x->src_sel0_bit.ch3_src = flexible_request; + } + else if(flex_channelx == FLEX_CHANNEL4) + { + dma_x->src_sel0_bit.ch4_src = flexible_request; + } + else if(flex_channelx == FLEX_CHANNEL5) + { + dma_x->src_sel1_bit.ch5_src = flexible_request; + } + else if(flex_channelx == FLEX_CHANNEL6) + { + dma_x->src_sel1_bit.ch6_src = flexible_request; + } + else + { + if(flex_channelx == FLEX_CHANNEL7) + { + dma_x->src_sel1_bit.ch7_src = flexible_request; + } + } +} + +/** + * @brief get dma interrupt flag + * @param dmax_flag + * this parameter can be one of the following values: + * - DMA1_FDT1_FLAG - DMA1_HDT1_FLAG - DMA1_DTERR1_FLAG + * - DMA1_FDT2_FLAG - DMA1_HDT2_FLAG - DMA1_DTERR2_FLAG + * - DMA1_FDT3_FLAG - DMA1_HDT3_FLAG - DMA1_DTERR3_FLAG + * - DMA1_FDT4_FLAG - DMA1_HDT4_FLAG - DMA1_DTERR4_FLAG + * - DMA1_FDT5_FLAG - DMA1_HDT5_FLAG - DMA1_DTERR5_FLAG + * - DMA1_FDT6_FLAG - DMA1_HDT6_FLAG - DMA1_DTERR6_FLAG + * - DMA1_FDT7_FLAG - DMA1_HDT7_FLAG - DMA1_DTERR7_FLAG + * - DMA2_FDT1_FLAG - DMA2_HDT1_FLAG - DMA2_DTERR1_FLAG + * - DMA2_FDT2_FLAG - DMA2_HDT2_FLAG - DMA2_DTERR2_FLAG + * - DMA2_FDT3_FLAG - DMA2_HDT3_FLAG - DMA2_DTERR3_FLAG + * - DMA2_FDT4_FLAG - DMA2_HDT4_FLAG - DMA2_DTERR4_FLAG + * - DMA2_FDT5_FLAG - DMA2_HDT5_FLAG - DMA2_DTERR5_FLAG + * - DMA2_FDT6_FLAG - DMA2_HDT6_FLAG - DMA2_DTERR6_FLAG + * - DMA2_FDT7_FLAG - DMA2_HDT7_FLAG - DMA2_DTERR7_FLAG + * @retval state of dma flag + */ +flag_status dma_interrupt_flag_get(uint32_t dmax_flag) +{ + flag_status status = RESET; + uint32_t temp = 0; + + if(dmax_flag > 0x10000000) + { + temp = DMA2->sts; + } + else + { + temp = DMA1->sts; + } + + if ((temp & dmax_flag) != (uint16_t)RESET) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @brief get dma flag + * @param dmax_flag + * this parameter can be one of the following values: + * - DMA1_GL1_FLAG - DMA1_FDT1_FLAG - DMA1_HDT1_FLAG - DMA1_DTERR1_FLAG + * - DMA1_GL2_FLAG - DMA1_FDT2_FLAG - DMA1_HDT2_FLAG - DMA1_DTERR2_FLAG + * - DMA1_GL3_FLAG - DMA1_FDT3_FLAG - DMA1_HDT3_FLAG - DMA1_DTERR3_FLAG + * - DMA1_GL4_FLAG - DMA1_FDT4_FLAG - DMA1_HDT4_FLAG - DMA1_DTERR4_FLAG + * - DMA1_GL5_FLAG - DMA1_FDT5_FLAG - DMA1_HDT5_FLAG - DMA1_DTERR5_FLAG + * - DMA1_GL6_FLAG - DMA1_FDT6_FLAG - DMA1_HDT6_FLAG - DMA1_DTERR6_FLAG + * - DMA1_GL7_FLAG - DMA1_FDT7_FLAG - DMA1_HDT7_FLAG - DMA1_DTERR7_FLAG + * - DMA2_GL1_FLAG - DMA2_FDT1_FLAG - DMA2_HDT1_FLAG - DMA2_DTERR1_FLAG + * - DMA2_GL2_FLAG - DMA2_FDT2_FLAG - DMA2_HDT2_FLAG - DMA2_DTERR2_FLAG + * - DMA2_GL3_FLAG - DMA2_FDT3_FLAG - DMA2_HDT3_FLAG - DMA2_DTERR3_FLAG + * - DMA2_GL4_FLAG - DMA2_FDT4_FLAG - DMA2_HDT4_FLAG - DMA2_DTERR4_FLAG + * - DMA2_GL5_FLAG - DMA2_FDT5_FLAG - DMA2_HDT5_FLAG - DMA2_DTERR5_FLAG + * - DMA2_GL6_FLAG - DMA2_FDT6_FLAG - DMA2_HDT6_FLAG - DMA2_DTERR6_FLAG + * - DMA2_GL7_FLAG - DMA2_FDT7_FLAG - DMA2_HDT7_FLAG - DMA2_DTERR7_FLAG + * @retval state of dma flag + */ +flag_status dma_flag_get(uint32_t dmax_flag) +{ + flag_status status = RESET; + uint32_t temp = 0; + + if(dmax_flag > 0x10000000) + { + temp = DMA2->sts; + } + else + { + temp = DMA1->sts; + } + + if ((temp & dmax_flag) != (uint16_t)RESET) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @brief clear dma flag + * @param dmax_flag + * this parameter can be one of the following values: + * - DMA1_GL1_FLAG - DMA1_FDT1_FLAG - DMA1_HDT1_FLAG - DMA1_DTERR1_FLAG + * - DMA1_GL2_FLAG - DMA1_FDT2_FLAG - DMA1_HDT2_FLAG - DMA1_DTERR2_FLAG + * - DMA1_GL3_FLAG - DMA1_FDT3_FLAG - DMA1_HDT3_FLAG - DMA1_DTERR3_FLAG + * - DMA1_GL4_FLAG - DMA1_FDT4_FLAG - DMA1_HDT4_FLAG - DMA1_DTERR4_FLAG + * - DMA1_GL5_FLAG - DMA1_FDT5_FLAG - DMA1_HDT5_FLAG - DMA1_DTERR5_FLAG + * - DMA1_GL6_FLAG - DMA1_FDT6_FLAG - DMA1_HDT6_FLAG - DMA1_DTERR6_FLAG + * - DMA1_GL7_FLAG - DMA1_FDT7_FLAG - DMA1_HDT7_FLAG - DMA1_DTERR7_FLAG + * - DMA2_GL1_FLAG - DMA2_FDT1_FLAG - DMA2_HDT1_FLAG - DMA2_DTERR1_FLAG + * - DMA2_GL2_FLAG - DMA2_FDT2_FLAG - DMA2_HDT2_FLAG - DMA2_DTERR2_FLAG + * - DMA2_GL3_FLAG - DMA2_FDT3_FLAG - DMA2_HDT3_FLAG - DMA2_DTERR3_FLAG + * - DMA2_GL4_FLAG - DMA2_FDT4_FLAG - DMA2_HDT4_FLAG - DMA2_DTERR4_FLAG + * - DMA2_GL5_FLAG - DMA2_FDT5_FLAG - DMA2_HDT5_FLAG - DMA2_DTERR5_FLAG + * - DMA2_GL6_FLAG - DMA2_FDT6_FLAG - DMA2_HDT6_FLAG - DMA2_DTERR6_FLAG + * - DMA2_GL7_FLAG - DMA2_FDT7_FLAG - DMA2_HDT7_FLAG - DMA2_DTERR7_FLAG + * @retval none + */ +void dma_flag_clear(uint32_t dmax_flag) +{ + if(dmax_flag > 0x10000000) + { + DMA2->clr = (uint32_t)(dmax_flag & 0x0FFFFFFF); + } + else + { + DMA1->clr = dmax_flag; + } +} + +/** + * @brief dma init config with its default value. + * @param dma_init_struct : pointer to a dma_init_type structure which will + * be initialized. + * @retval none + */ +void dma_default_para_init(dma_init_type* dma_init_struct) +{ + dma_init_struct->peripheral_base_addr = 0x0; + dma_init_struct->memory_base_addr = 0x0; + dma_init_struct->direction = DMA_DIR_PERIPHERAL_TO_MEMORY; + dma_init_struct->buffer_size = 0x0; + dma_init_struct->peripheral_inc_enable = FALSE; + dma_init_struct->memory_inc_enable = FALSE; + dma_init_struct->peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE; + dma_init_struct->memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE; + dma_init_struct->loop_mode_enable = FALSE; + dma_init_struct->priority = DMA_PRIORITY_LOW; +} + +/** + * @brief dma init + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * - DMA2_CHANNEL1 + * - DMA2_CHANNEL2 + * - DMA2_CHANNEL3 + * - DMA2_CHANNEL4 + * - DMA2_CHANNEL5 + * - DMA2_CHANNEL6 + * - DMA2_CHANNEL7 + * @param dma_initstruct : pointer to a dma_init_type structure. + * @retval none + */ +void dma_init(dma_channel_type* dmax_channely, dma_init_type* dma_init_struct) +{ + /* clear ctrl register dtd bit and m2m bit */ + dmax_channely->ctrl &= 0xbfef; + dmax_channely->ctrl |= dma_init_struct->direction; + + dmax_channely->ctrl_bit.chpl = dma_init_struct->priority; + dmax_channely->ctrl_bit.mwidth = dma_init_struct->memory_data_width; + dmax_channely->ctrl_bit.pwidth = dma_init_struct->peripheral_data_width; + dmax_channely->ctrl_bit.mincm = dma_init_struct->memory_inc_enable; + dmax_channely->ctrl_bit.pincm = dma_init_struct->peripheral_inc_enable; + dmax_channely->ctrl_bit.lm = dma_init_struct->loop_mode_enable; + dmax_channely->dtcnt = dma_init_struct->buffer_size; + dmax_channely->paddr = dma_init_struct->peripheral_base_addr; + dmax_channely->maddr = dma_init_struct->memory_base_addr; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f403a_407_emac.c b/libraries/drivers/src/at32f403a_407_emac.c new file mode 100644 index 0000000..5d65166 --- /dev/null +++ b/libraries/drivers/src/at32f403a_407_emac.c @@ -0,0 +1,2453 @@ +/** + ************************************************************************** + * @file at32f403a_407_emac.c + * @brief contains all the functions for the emac firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup EMAC + * @brief EMAC driver modules + * @{ + */ + +#ifdef EMAC_MODULE_ENABLED + +/** @defgroup EMAC_private_functions + * @{ + */ + +#if defined (EMAC_BASE) +/** + * @brief global pointers on tx and rx descriptor used to track transmit and receive descriptors + */ +__IO emac_dma_desc_type *dma_tx_desc_to_set; +__IO emac_dma_desc_type *dma_rx_desc_to_get; +__IO emac_dma_desc_type *ptp_dma_tx_desc_to_set; +__IO emac_dma_desc_type *ptp_dma_rx_desc_to_get; + +/* emac private function */ +static void emac_delay(uint32_t delay); + +/** + * @brief deinitialize the emac peripheral registers to their default reset values. + * @param none + * @retval none + */ +void emac_reset(void) +{ + crm_periph_reset(CRM_EMAC_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_EMAC_PERIPH_RESET, FALSE); +} + +/** + * @brief initialize emac control structure + * @param emac_control_config_type + * @retval none + */ +void emac_control_para_init(emac_control_config_type *control_para) +{ + control_para->auto_nego = EMAC_AUTO_NEGOTIATION_OFF; + control_para->auto_pad_crc_strip = FALSE; + control_para->back_off_limit = EMAC_BACKOFF_LIMIT_0; + control_para->carrier_sense_disable = FALSE; + control_para->deferral_check = FALSE; + control_para->duplex_mode = EMAC_HALF_DUPLEX; + control_para->fast_ethernet_speed = EMAC_SPEED_10MBPS; + control_para->interframe_gap = EMAC_INTERFRAME_GAP_96BIT; + control_para->ipv4_checksum_offload = FALSE; + control_para->jabber_disable = FALSE; + control_para->loopback_mode = FALSE; + control_para->receive_own_disable = FALSE; + control_para->retry_disable = FALSE; + control_para->watchdog_disable = FALSE; +} + +/** + * @brief according to hclk to set mdc clock frequency. + * @param none + * @retval none + */ +void emac_clock_range_set(void) +{ + uint8_t bits_value = 0; + crm_clocks_freq_type clocks_freq = {0}; + + /* clear clock range bits */ + EMAC->miiaddr_bit.cr = bits_value; + + crm_clocks_freq_get(&clocks_freq); + + if((clocks_freq.ahb_freq >= EMAC_HCLK_BORDER_20MHZ) && (clocks_freq.ahb_freq < EMAC_HCLK_BORDER_35MHZ)) + { + bits_value = EMAC_CLOCK_RANGE_20_TO_35; + } + else if((clocks_freq.ahb_freq >= EMAC_HCLK_BORDER_35MHZ) && (clocks_freq.ahb_freq < EMAC_HCLK_BORDER_60MHZ)) + { + bits_value = EMAC_CLOCK_RANGE_35_TO_60; + } + else if((clocks_freq.ahb_freq >= EMAC_HCLK_BORDER_60MHZ) && (clocks_freq.ahb_freq < EMAC_HCLK_BORDER_100MHZ)) + { + bits_value = EMAC_CLOCK_RANGE_60_TO_100; + } + else if((clocks_freq.ahb_freq >= EMAC_HCLK_BORDER_100MHZ) && (clocks_freq.ahb_freq < EMAC_HCLK_BORDER_150MHZ)) + { + bits_value = EMAC_CLOCK_RANGE_100_TO_150; + } + else if((clocks_freq.ahb_freq >= EMAC_HCLK_BORDER_150MHZ) && (clocks_freq.ahb_freq <= EMAC_HCLK_BORDER_240MHZ)) + { + bits_value = EMAC_CLOCK_RANGE_150_TO_240; + } + + EMAC->miiaddr_bit.cr = bits_value; +} + +/** + * @brief configure emac control setting. + * @param control_struct: control setting of mac control register. + * @retval none + */ +void emac_control_config(emac_control_config_type *control_struct) +{ + emac_deferral_check_set(control_struct->deferral_check); + emac_backoff_limit_set(control_struct->back_off_limit); + emac_auto_pad_crc_stripping_set(control_struct->auto_pad_crc_strip); + emac_retry_disable(control_struct->retry_disable); + emac_ipv4_checksum_offload_set(control_struct->ipv4_checksum_offload); + emac_loopback_mode_enable(control_struct->loopback_mode); + emac_receive_own_disable(control_struct->receive_own_disable); + emac_carrier_sense_disable(control_struct->carrier_sense_disable); + emac_interframe_gap_set(control_struct->interframe_gap); + emac_jabber_disable(control_struct->jabber_disable); + emac_watchdog_disable(control_struct->watchdog_disable); +} + +/** + * @brief reset emac dma + * @param none + * @retval none + */ +void emac_dma_software_reset_set(void) +{ + EMAC_DMA->bm_bit.swr = 1; +} + +/** + * @brief get emac dma reset status + * @param none + * @retval TRUE of FALSE + */ +flag_status emac_dma_software_reset_get(void) +{ + if(EMAC_DMA->bm_bit.swr) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief enable emac and dma reception/transmission + * @param none + * @retval none + */ +void emac_start(void) +{ + /* enable transmit state machine of the mac for transmission on the mii */ + emac_trasmitter_enable(TRUE); + + /* flush transmit fifo */ + emac_dma_operations_set(EMAC_DMA_OPS_FLUSH_TRANSMIT_FIFO, TRUE); + + /* enable receive state machine of the mac for reception from the mii */ + emac_receiver_enable(TRUE); + + /* start dma transmission */ + emac_dma_operations_set(EMAC_DMA_OPS_START_STOP_TRANSMIT, TRUE); + + /* start dma reception */ + emac_dma_operations_set(EMAC_DMA_OPS_START_STOP_RECEIVE, TRUE); +} + +/** + * @brief stop emac and dma reception/transmission + * @param none + * @retval none + */ +void emac_stop(void) +{ + /* stop dma transmission */ + emac_dma_operations_set(EMAC_DMA_OPS_START_STOP_TRANSMIT, FALSE); + + /* stop dma reception */ + emac_dma_operations_set(EMAC_DMA_OPS_START_STOP_RECEIVE, FALSE); + + /* stop receive state machine of the mac for reception from the mii */ + emac_receiver_enable(FALSE); + + /* flush transmit fifo */ + emac_dma_operations_set(EMAC_DMA_OPS_FLUSH_TRANSMIT_FIFO, TRUE); + + /* stop transmit state machine of the mac for transmission on the mii */ + emac_trasmitter_enable(FALSE); +} + +/** + * @brief write phy data. + * @param address: phy address. + * @param reg: register of phy. + * @param data: value that wants to write to phy. + * @retval SUCCESS or ERROR + */ +error_status emac_phy_register_write(uint8_t address, uint8_t reg, uint16_t data) +{ + uint32_t timeout = 0; + + EMAC->miidt_bit.md = data; + + EMAC->miiaddr_bit.pa = address; + EMAC->miiaddr_bit.mii = reg; + EMAC->miiaddr_bit.mw = 1; + EMAC->miiaddr_bit.mb = 1; + + do + { + timeout++; + } while((EMAC->miiaddr_bit.mb) && (timeout < PHY_TIMEOUT)); + + if(timeout == PHY_TIMEOUT) + { + return ERROR; + } + return SUCCESS; +} + +/** + * @brief read phy data + * @param address: phy address. + * @param reg: register of phy. + * @param data: value that is read from phy. + * @retval SUCCESS or ERROR + */ +error_status emac_phy_register_read(uint8_t address, uint8_t reg, uint16_t *data) +{ + uint32_t timeout = 0; + + EMAC->miiaddr_bit.pa = address; + EMAC->miiaddr_bit.mii = reg; + EMAC->miiaddr_bit.mw = 0; + EMAC->miiaddr_bit.mb = 1; + + do + { + timeout++; + *data = EMAC->miidt_bit.md; + } while((EMAC->miiaddr_bit.mb) && (timeout < PHY_TIMEOUT)); + + if(timeout == PHY_TIMEOUT) + { + return ERROR; + } + + *data = EMAC->miidt_bit.md; + return SUCCESS; +} + +/** + * @brief emac receiver enable. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_receiver_enable(confirm_state new_state) +{ + __IO uint32_t temp = 0; + + EMAC->ctrl_bit.re = new_state; + + temp = EMAC->ctrl; + emac_delay(1); + EMAC->ctrl = temp; +} + +/** + * @brief emac transmitter enable. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_trasmitter_enable(confirm_state new_state) +{ + __IO uint32_t temp = 0; + + EMAC->ctrl_bit.te = new_state; + + temp = EMAC->ctrl; + emac_delay(1); + EMAC->ctrl = temp; +} + +/** + * @brief emac defferal check enable, only avalible in half-duplex mode. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_deferral_check_set(confirm_state new_state) +{ + EMAC->ctrl_bit.dc = new_state; +} + +/** + * @brief emac back-off limit, only avalible in half-duplex mode. + * @param slot_time: waiting time of retransmission after collision + * this parameter can be one of the following values: + * - EMAC_BACKOFF_LIMIT_0 + * - EMAC_BACKOFF_LIMIT_1 + * - EMAC_BACKOFF_LIMIT_2 + * - EMAC_BACKOFF_LIMIT_3 + * @retval none + */ +void emac_backoff_limit_set(emac_bol_type slot_time) +{ + EMAC->ctrl_bit.bl = slot_time; +} + +/** + * @brief set mac automatic pad/CRC stripping. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_auto_pad_crc_stripping_set(confirm_state new_state) +{ + EMAC->ctrl_bit.acs = new_state; +} + +/** + * @brief transmittion retry disable. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_retry_disable(confirm_state new_state) +{ + EMAC->ctrl_bit.dr = new_state; +} + +/** + * @brief set ipv4 checksum offload. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ipv4_checksum_offload_set(confirm_state new_state) +{ + EMAC->ctrl_bit.ipc = new_state; +} + +/** + * @brief enable loopback mode. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_loopback_mode_enable(confirm_state new_state) +{ + EMAC->ctrl_bit.lm = new_state; +} + +/** + * @brief receive own disable. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_receive_own_disable(confirm_state new_state) +{ + EMAC->ctrl_bit.dro = new_state; +} + +/** + * @brief carrier sense disbale. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_carrier_sense_disable(confirm_state new_state) +{ + EMAC->ctrl_bit.dcs = new_state; +} + +/** + * @brief set minimum interframe gap between frames during transmission. + * @param number: interframe gap number. + * this parameter can be one of the following values: + * - EMAC_FRAME_GAP_96BIT + * - EMAC_FRAME_GAP_88BIT + * - EMAC_FRAME_GAP_80BIT + * - EMAC_FRAME_GAP_72BIT + * - EMAC_FRAME_GAP_64BIT + * - EMAC_FRAME_GAP_56BIT + * - EMAC_FRAME_GAP_48BIT + * - EMAC_FRAME_GAP_40BIT + * @retval none + */ +void emac_interframe_gap_set(emac_intergrame_gap_type number) +{ + EMAC->ctrl_bit.ifg = number; +} + +/** + * @brief jabber disable. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_jabber_disable(confirm_state new_state) +{ + EMAC->ctrl_bit.jd = new_state; +} + +/** + * @brief watchdog disable. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_watchdog_disable(confirm_state new_state) +{ + EMAC->ctrl_bit.wd = new_state; +} + +/** + * @brief set mac fast emac speed. + * @param speed: mac bandwidth + * this parameter can be one of the following values: + * - EMAC_SPEED_10MBPS + * - EMAC_SPEED_100MBPS + * @retval none + */ +void emac_fast_speed_set(emac_speed_type speed) +{ + EMAC->ctrl_bit.fes = speed; +} + +/** + * @brief set duplex mode. + * @param duplex_mode: communication mode + * this parameter can be one of the following values: + * - EMAC_HALF_DUPLEX + * - EMAC_FULL_DUPLEX + * @retval none + */ +void emac_duplex_mode_set(emac_duplex_type duplex_mode) +{ + EMAC->ctrl_bit.dm = duplex_mode; +} + +/** + * @brief set mac promiscuous mode. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_promiscuous_mode_set(confirm_state new_state) +{ + EMAC->frmf_bit.pr = new_state; +} + +/** + * @brief hash unicast. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_hash_unicast_set(confirm_state new_state) +{ + EMAC->frmf_bit.huc = new_state; +} + +/** + * @brief hash multicast. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_hash_multicast_set(confirm_state new_state) +{ + EMAC->frmf_bit.hmc = new_state; +} + +/** + * @brief destination address inverse filtering. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_dstaddr_inverse_filter_set(confirm_state new_state) +{ + EMAC->frmf_bit.daif = new_state; +} + +/** + * @brief pass all multicasting frames. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_pass_all_multicasting_set(confirm_state new_state) +{ + EMAC->frmf_bit.pmc = new_state; +} + +/** + * @brief broadcast frames disable. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_broadcast_frames_disable(confirm_state new_state) +{ + EMAC->frmf_bit.dbf = new_state; +} + +/** + * @brief set mac how to pass control frames. + * @param condition: set what control frame can pass filter. + * this parameter can be one of the following values: + * - EMAC_CONTROL_FRAME_PASSING_NO + * - EMAC_CONTROL_FRAME_PASSING_ALL_EXCEPT_PAUSE + * - EMAC_CONTROL_FRAME_PASSING_ALL + * - EMAC_CONTROL_FRAME_PASSING_MATCH + * @retval none + */ +void emac_pass_control_frames_set(emac_control_frames_filter_type condition) +{ + EMAC->frmf_bit.pcf = condition; +} + +/** + * @brief source address inverse filtering. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_srcaddr_inverse_filter_set(confirm_state new_state) +{ + EMAC->frmf_bit.saif = new_state; +} + +/** + * @brief source address filtering. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_srcaddr_filter_set(confirm_state new_state) +{ + EMAC->frmf_bit.saf = new_state; +} + +/** + * @brief mac uses hash or perfect filter. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_hash_perfect_filter_set(confirm_state new_state) +{ + EMAC->frmf_bit.hpf = new_state; +} + +/** + * @brief mac receives all frames. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_receive_all_set(confirm_state new_state) +{ + EMAC->frmf_bit.ra = new_state; +} + +/** + * @brief hash table high 32-bit. + * @param high32bits: the highest 32-bit of hash table. + * @retval none + */ +void emac_hash_table_high32bits_set(uint32_t high32bits) +{ + EMAC->hth_bit.hth = high32bits; +} + +/** + * @brief hash table low 32-bit. + * @param low32bits: the lowest 32-bit of hash table. + * @retval none + */ +void emac_hash_table_low32bits_set(uint32_t low32bits) +{ + EMAC->htl_bit.htl = low32bits; +} + +/** + * @brief mii busy status. + * @param none + * @retval SET or RESET + */ +flag_status emac_mii_busy_get(void) +{ + if(EMAC->miiaddr_bit.mb) { + return SET; + } + else { + return RESET; + } +} + +/** + * @brief tell phy that will be written. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_mii_write(confirm_state new_state) +{ + EMAC->miiaddr_bit.mw = new_state; +} + +/** + * @brief set flow control busy in full-duplex mode, back pressure activate in half-duplex mode. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_fcb_bpa_set(confirm_state new_state) +{ + EMAC->fctrl_bit.fcbbpa = new_state; +} + +/** + * @brief set transmit flow control. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_transmit_flow_control_enable(confirm_state new_state) +{ + EMAC->fctrl_bit.etf = new_state; +} + +/** + * @brief set receive flow control. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_receive_flow_control_enable(confirm_state new_state) +{ + EMAC->fctrl_bit.erf = new_state; +} + +/** + * @brief set unicast pause frame detect. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_unicast_pause_frame_detect(confirm_state new_state) +{ + EMAC->fctrl_bit.dup = new_state; +} + +/** + * @brief set pause low threshold. + * @param pasue_threshold: pause slot time. + * this parameter can be one of the following values: + * - EMAC_PAUSE_4_SLOT_TIME + * - EMAC_PAUSE_28_SLOT_TIME + * - EMAC_PAUSE_144_SLOT_TIME + * - EMAC_PAUSE_256_SLOT_TIME + * @retval none + */ +void emac_pause_low_threshold_set(emac_pause_slot_threshold_type pasue_threshold) +{ + EMAC->fctrl_bit.plt = pasue_threshold; +} + +/** + * @brief set zero-quanta pause disable. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_zero_quanta_pause_disable(confirm_state new_state) +{ + EMAC->fctrl_bit.dzqp = new_state; +} + +/** + * @brief set pause time. + * @param pause_time: time slots to pause transmit frame. + * @retval none + */ +void emac_pause_time_set(uint16_t pause_time) +{ + EMAC->fctrl_bit.pt = pause_time; +} + +/** + * @brief identify coming vlan frame field with setting value. + * @param identifier: it will be compared with coming frame. + * @retval none + */ +void emac_vlan_tag_identifier_set(uint16_t identifier) +{ + EMAC->vlt_bit.vti = identifier; +} + +/** + * @brief set 12-bit vlan identifier. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_vlan_tag_comparison_set(confirm_state new_state) +{ + EMAC->vlt_bit.etv = new_state; +} + +/** + * @brief set wakeup frame. + * @param value: it will be written to eight non transparent registers. + * @retval none + */ +void emac_wakeup_frame_set(uint32_t value) +{ + EMAC->rwff = value; +} + +/** + * @brief get wakeup frame. + * @param none + * @retval get value from eight non transparent registers. + */ +uint32_t emac_wakeup_frame_get(void) +{ + return (EMAC->rwff); +} + +/** + * @brief all frame will be droppped except wakeup frame or magic packet. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_power_down_set(confirm_state new_state) +{ + EMAC->pmtctrlsts_bit.pd = new_state; +} + +/** + * @brief magic packet enable + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_magic_packet_enable(confirm_state new_state) +{ + EMAC->pmtctrlsts_bit.emp = new_state; +} + +/** + * @brief wakeup frame enable + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_wakeup_frame_enable(confirm_state new_state) +{ + EMAC->pmtctrlsts_bit.erwf = new_state; +} + +/** + * @brief received magic packet + * @param none + * @retval the new state of usart_flag (SET or RESET). + */ +flag_status emac_received_magic_packet_get(void) +{ + if(EMAC->pmtctrlsts_bit.rmp) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief received wakeup frame. + * @param none + * @retval the new state of usart_flag (SET or RESET). + */ +flag_status emac_received_wakeup_frame_get(void) +{ + if(EMAC->pmtctrlsts_bit.rrwf) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief set unicast frame that passes DAF as wakeup frame. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_global_unicast_set(confirm_state new_state) +{ + EMAC->pmtctrlsts_bit.guc = new_state; +} + +/** + * @brief reset wakeup frame filter resgister + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_wakeup_frame_filter_reset(confirm_state new_state) +{ + EMAC->pmtctrlsts_bit.rwffpr = new_state; +} + +/** + * @brief read interrupt status + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - EMAC_PMT_FLAG + * - EMAC_MMC_FLAG + * - EMAC_MMCR_FLAG + * - EMAC_MMCT_FLAG + * - EMAC_TST_FLAG + * @retval the new state of usart_flag (SET or RESET). + */ +flag_status emac_interrupt_status_read(uint32_t flag) +{ + if(EMAC->ists & flag) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief set interrupt mask + * @param mask_type: mask the interrupt signal + * this parameter can be one of the following values: + * - EMAC_INTERRUPT_PMT_MASK + * - EMAC_INTERRUPT_TST_MASK + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_interrupt_mask_set(emac_interrupt_mask_type mask_type, confirm_state new_state) +{ + switch(mask_type) + { + case EMAC_INTERRUPT_PMT_MASK: + { + EMAC->imr_bit.pim = new_state; + break; + } + case EMAC_INTERRUPT_TST_MASK: + { + EMAC->imr_bit.tim = new_state; + break; + } + } +} + +/** + * @brief set local mac address + * @param address: local address for mac0 + * @retval none + */ +void emac_local_address_set(uint8_t *address) +{ + EMAC->a0h_bit.ma0h = (uint32_t)(address[5] << 8 | address[4]); + EMAC->a0l_bit.ma0l = (uint32_t)(address[3] << 24 | address[2] << 16 | address[1] << 8 | address[0]); +} + +/** + * @brief set mac filter address + * @param mac: select which mac you want to set + * this parameter can be one of the following values: + * - EMAC_ADDRESS_FILTER_1 + * - EMAC_ADDRESS_FILTER_2 + * - EMAC_ADDRESS_FILTER_3 + * @retval none + */ +void emac_address_filter_set(emac_address_type mac, emac_address_filter_type filter, emac_address_mask_type mask_bit, confirm_state new_state) +{ + switch(mac) + { + case EMAC_ADDRESS_FILTER_1: + { + EMAC->a1h_bit.sa = filter; + EMAC->a1h_bit.mbc = mask_bit; + EMAC->a1h_bit.ae = new_state; + break; + } + case EMAC_ADDRESS_FILTER_2: + { + EMAC->a2h_bit.sa = filter; + EMAC->a2h_bit.mbc = mask_bit; + EMAC->a2h_bit.ae = new_state; + break; + } + case EMAC_ADDRESS_FILTER_3: + { + EMAC->a3h_bit.sa = filter; + EMAC->a3h_bit.mbc = mask_bit; + EMAC->a3h_bit.ae = new_state; + break; + } + } +} + +/** + * @brief set transmit/receive descriptor list address + * @param transfer_type: it will be transmit or receive + * this parameter can be one of the following values: + * - EMAC_DMA_TRANSMIT + * - EMAC_DMA_RECEIVE + * @param dma_desc_tab: pointer on the first tx desc list + * @param buff: pointer on the first tx/rx buffer list + * @param buffer_count: number of the used Tx desc in the list + * @retval none + */ +void emac_dma_descriptor_list_address_set(emac_dma_tx_rx_type transfer_type, emac_dma_desc_type *dma_desc_tab, uint8_t *buff, uint32_t buffer_count) +{ + uint32_t i = 0; + emac_dma_desc_type *dma_descriptor; + + switch(transfer_type) + { + case EMAC_DMA_TRANSMIT: + { + dma_tx_desc_to_set = dma_desc_tab; + for(i = 0; i < buffer_count; i++) + { + dma_descriptor = dma_desc_tab + i; + + dma_descriptor->status = EMAC_DMATXDESC_TCH; + + dma_descriptor->buf1addr = (uint32_t)(&buff[i * EMAC_MAX_PACKET_LENGTH]); + + if(i < (buffer_count - 1)) + { + dma_descriptor->buf2nextdescaddr = (uint32_t)(dma_desc_tab + i + 1); + } + else + { + dma_descriptor->buf2nextdescaddr = (uint32_t) dma_desc_tab; + } + } + EMAC_DMA->tdladdr_bit.stl = (uint32_t) dma_desc_tab; + break; + } + case EMAC_DMA_RECEIVE: + { + dma_rx_desc_to_get = dma_desc_tab; + for(i = 0; i < buffer_count; i++) + { + dma_descriptor = dma_desc_tab + i; + + dma_descriptor->status = EMAC_DMARXDESC_OWN; + + dma_descriptor->controlsize = EMAC_DMARXDESC_RCH | (uint32_t)EMAC_MAX_PACKET_LENGTH; + + dma_descriptor->buf1addr = (uint32_t)(&buff[i * EMAC_MAX_PACKET_LENGTH]); + + if(i < (buffer_count - 1)) + { + dma_descriptor->buf2nextdescaddr = (uint32_t)(dma_desc_tab + i + 1); + } + else + { + dma_descriptor->buf2nextdescaddr = (uint32_t) dma_desc_tab; + } + } + EMAC_DMA->rdladdr_bit.srl = (uint32_t) dma_desc_tab; + break; + } + } +} + +/** + * @brief set transmit/receive descriptor list address + * @param transfer_type: it will be transmit or receive + * this parameter can be one of the following values: + * - EMAC_DMA_TRANSMIT + * - EMAC_DMA_RECEIVE + * @param dma_desc_tab: pointer on the first tx desc list + * @param buff: pointer on the first tx/rx buffer list + * @param buffer_count: number of the used Tx desc in the list + * @retval none + */ +void emac_ptp_dma_descriptor_list_address_set(emac_dma_tx_rx_type transfer_type, emac_dma_desc_type *dma_desc_tab, emac_dma_desc_type *ptp_dma_desc_tab, uint8_t *buff, uint32_t buffer_count) +{ + uint32_t i = 0; + emac_dma_desc_type *dma_descriptor; + + switch(transfer_type) + { + case EMAC_DMA_TRANSMIT: + { + dma_tx_desc_to_set = dma_desc_tab; + ptp_dma_tx_desc_to_set = ptp_dma_desc_tab; + + for(i = 0; i < buffer_count; i++) + { + dma_descriptor = dma_desc_tab + i; + + dma_descriptor->status = EMAC_DMATXDESC_TCH | EMAC_DMATXDESC_TTSE; + + dma_descriptor->buf1addr = (uint32_t)(&buff[i * EMAC_MAX_PACKET_LENGTH]); + + if(i < (buffer_count - 1)) + { + dma_descriptor->buf2nextdescaddr = (uint32_t)(dma_desc_tab + i + 1); + } + else + { + dma_descriptor->buf2nextdescaddr = (uint32_t) dma_desc_tab; + } + + (&ptp_dma_desc_tab[i])->buf1addr = dma_descriptor->buf1addr; + (&ptp_dma_desc_tab[i])->buf2nextdescaddr = dma_descriptor->buf2nextdescaddr; + } + + (&ptp_dma_desc_tab[i-1])->status = (uint32_t) ptp_dma_desc_tab; + + EMAC_DMA->tdladdr_bit.stl = (uint32_t) dma_desc_tab; + break; + } + case EMAC_DMA_RECEIVE: + { + dma_rx_desc_to_get = dma_desc_tab; + ptp_dma_rx_desc_to_get = ptp_dma_desc_tab; + + for(i = 0; i < buffer_count; i++) + { + dma_descriptor = dma_desc_tab + i; + + dma_descriptor->status = EMAC_DMARXDESC_OWN; + + dma_descriptor->controlsize = EMAC_DMARXDESC_RCH | (uint32_t)EMAC_MAX_PACKET_LENGTH; + + dma_descriptor->buf1addr = (uint32_t)(&buff[i * EMAC_MAX_PACKET_LENGTH]); + + if(i < (buffer_count - 1)) + { + dma_descriptor->buf2nextdescaddr = (uint32_t)(dma_desc_tab + i + 1); + } + else + { + dma_descriptor->buf2nextdescaddr = (uint32_t) dma_desc_tab; + } + + (&ptp_dma_desc_tab[i])->buf1addr = dma_descriptor->buf1addr; + (&ptp_dma_desc_tab[i])->buf2nextdescaddr = dma_descriptor->buf2nextdescaddr; + } + + (&ptp_dma_desc_tab[i-1])->status = (uint32_t) ptp_dma_desc_tab; + + EMAC_DMA->rdladdr_bit.srl = (uint32_t) dma_desc_tab; + break; + } + } +} +/** + * @brief enable or disable the specified dma rx descriptor receive interrupt + * @param dma_rx_desc: pointer on a rx desc. + * @param new_state: new state of the specified dma rx descriptor interrupt. + * this parameter can be one of the following values: + * - TRUE + * - FALSE. + * @retval none + */ +void emac_dma_rx_desc_interrupt_config(emac_dma_desc_type *dma_rx_desc, confirm_state new_state) +{ + if (new_state != FALSE) + { + /* enable the dma rx desc receive interrupt */ + dma_rx_desc->controlsize &= (~(uint32_t)EMAC_DMARXDESC_DIC); + } + else + { + /* disable the dma rx desc receive interrupt */ + dma_rx_desc->controlsize |= EMAC_DMARXDESC_DIC; + } +} + +/** + * @brief get transmit/receive descriptor list address + * @param transfer_type: it will be transmit or receive + * this parameter can be one of the following values: + * - EMAC_DMA_TRANSMIT + * - EMAC_DMA_RECEIVE + * @retval transmit/receive descriptor list address + */ +uint32_t emac_dma_descriptor_list_address_get(emac_dma_tx_rx_type transfer_type) +{ + switch(transfer_type) + { + case EMAC_DMA_TRANSMIT: + { + return (EMAC_DMA->tdladdr_bit.stl); + } + case EMAC_DMA_RECEIVE: + { + return (EMAC_DMA->rdladdr_bit.srl); + } + } + return 0; +} + +/** + * @brief get the size of received the received packet. + * @param none + * @retval received packet size + */ +uint32_t emac_received_packet_size_get(void) +{ + uint32_t frame_length = 0; + if(((dma_rx_desc_to_get->status & EMAC_DMARXDESC_OWN) == (uint32_t)RESET) && + ((dma_rx_desc_to_get->status & EMAC_DMATXDESC_ES) == (uint32_t)RESET) && + ((dma_rx_desc_to_get->status & EMAC_DMARXDESC_LS) != (uint32_t)RESET) && + ((dma_rx_desc_to_get->status & EMAC_DMARXDESC_FS) != (uint32_t)RESET)) + { + frame_length = emac_dmarxdesc_frame_length_get((emac_dma_desc_type*) dma_rx_desc_to_get); + } + + return frame_length; +} + +/** + * @brief get the specified dma rx descsriptor frame length. + * @param dma_rx_desc: pointer on a dma rx descriptor + * @retval the rx descriptor received frame length. + */ +uint32_t emac_dmarxdesc_frame_length_get(emac_dma_desc_type *dma_rx_desc) +{ + return ((dma_rx_desc->status & EMAC_DMARXDESC_FL) >> EMAC_DMARXDESC_FRAME_LENGTHSHIFT); +} + +/** + * @brief init emac dma parameters + * @param emac_dma_config_type + * @retval none + */ +void emac_dma_para_init(emac_dma_config_type *control_para) +{ + control_para->aab_enable = FALSE; + control_para->da_enable = FALSE; + control_para->desc_skip_length = 0; + control_para->dt_disable = FALSE; + control_para->fb_enable = FALSE; + control_para->fef_enable = FALSE; + control_para->flush_rx_disable = FALSE; + control_para->fugf_enable = FALSE; + control_para->osf_enable = FALSE; + control_para->priority_ratio = EMAC_DMA_1_RX_1_TX; + control_para->rsf_enable = FALSE; + control_para->rx_dma_pal = EMAC_DMA_PBL_1; + control_para->rx_threshold = EMAC_DMA_RX_THRESHOLD_64_BYTES; + control_para->tsf_enable = FALSE; + control_para->tx_dma_pal = EMAC_DMA_PBL_1; + control_para->tx_threshold = EMAC_DMA_TX_THRESHOLD_64_BYTES; + control_para->usp_enable = FALSE; +} + +/** + * @brief configure emac dma + * @param emac_dma_config_type + * @retval none + */ +void emac_dma_config(emac_dma_config_type *control_para) +{ + EMAC_DMA->bm_bit.aab = control_para->aab_enable; + EMAC_DMA->bm_bit.dsl = control_para->desc_skip_length; + EMAC_DMA->bm_bit.rdp = control_para->rx_dma_pal; + EMAC_DMA->bm_bit.pbl = control_para->tx_dma_pal; + EMAC_DMA->bm_bit.fb = control_para->fb_enable; + EMAC_DMA->bm_bit.usp = control_para->usp_enable; + EMAC_DMA->bm_bit.da = control_para->da_enable; + EMAC_DMA->bm_bit.pr = control_para->priority_ratio; + + EMAC_DMA->opm_bit.dt = control_para->dt_disable; + EMAC_DMA->opm_bit.rsf = control_para->rsf_enable; + EMAC_DMA->opm_bit.dfrf = control_para->flush_rx_disable; + EMAC_DMA->opm_bit.tsf = control_para->tsf_enable; + EMAC_DMA->opm_bit.ttc = control_para->tx_threshold; + EMAC_DMA->opm_bit.fef = control_para->fef_enable; + EMAC_DMA->opm_bit.fugf = control_para->fugf_enable; + EMAC_DMA->opm_bit.rtc = control_para->rx_threshold; + EMAC_DMA->opm_bit.osf = control_para->osf_enable; +} + +/** + * @brief set rx tx priority + * @param ratio: rx tx priority ratio + * this parameter can be one of the following values: + * - EMAC_DMA_1_RX_1_TX + * - EMAC_DMA_2_RX_1_TX + * - EMAC_DMA_3_RX_1_TX + * - EMAC_DMA_4_RX_1_TX + * @param new_state: TRUE or FALSE + * @retval none + */ +void emac_dma_arbitation_set(emac_dma_rx_tx_ratio_type ratio, confirm_state new_state) +{ + EMAC_DMA->bm_bit.da = new_state; + + if(new_state) + { + EMAC_DMA->bm_bit.pr = ratio; + } +} + +/** + * @brief set descriptor skip mength + * @param length: descriptor skip length + * @retval none + */ +void emac_dma_descriptor_skip_length_set(uint8_t length) +{ + EMAC_DMA->bm_bit.dsl = length; +} + +/** + * @brief set programmable burst length + * @param tx_length: tx programmable burst length + * this parameter can be one of the following values: + * - EMAC_DMA_PBL_1 + * - EMAC_DMA_PBL_2 + * - EMAC_DMA_PBL_4 + * - EMAC_DMA_PBL_8 + * - EMAC_DMA_PBL_16 + * - EMAC_DMA_PBL_32 + * @param rx_length: rx programmable burst length + * this parameter can be one of the following values: + * - EMAC_DMA_PBL_1 + * - EMAC_DMA_PBL_2 + * - EMAC_DMA_PBL_4 + * - EMAC_DMA_PBL_8 + * - EMAC_DMA_PBL_16 + * - EMAC_DMA_PBL_32 + * @param new_state: TRUE or FALSE + * @retval none + */ +void emac_dma_separate_pbl_set(emac_dma_pbl_type tx_length, emac_dma_pbl_type rx_length, confirm_state new_state) +{ + EMAC_DMA->bm_bit.usp = new_state; + EMAC_DMA->bm_bit.pbl = tx_length; + + if(new_state) + { + EMAC_DMA->bm_bit.pbl = rx_length; + } +} + +/** + * @brief set 8 times programmable burst length + * @param new_state: TRUE or FALSE + * @retval none + */ +void emac_dma_eight_pbl_mode_set(confirm_state new_state) +{ + EMAC_DMA->bm_bit.pblx8 = new_state; +} + +/** + * @brief set address-aligned beats + * @param new_state: TRUE or FALSE + * @retval none + */ +void emac_dma_address_aligned_beats_set(confirm_state new_state) +{ + EMAC_DMA->bm_bit.aab = new_state; +} + +/** + * @brief set transmit/receive poll demand + * @param transfer_type: it will be transmit or receive + * this parameter can be one of the following values: + * - EMAC_DMA_TRANSMIT + * - EMAC_DMA_RECEIVE + * @param value: it can be any number + * @retval none + */ +void emac_dma_poll_demand_set(emac_dma_tx_rx_type transfer_type, uint32_t value) +{ + switch(transfer_type) + { + case EMAC_DMA_TRANSMIT: + { + EMAC_DMA->tpd_bit.tpd = value; + break; + } + case EMAC_DMA_RECEIVE: + { + EMAC_DMA->rpd_bit.rpd = value; + break; + } + } +} + +/** + * @brief get transmit poll demand + * @param transfer_type: it will be transmit or receive + * this parameter can be one of the following values: + * - EMAC_DMA_TRANSMIT + * - EMAC_DMA_RECEIVE + * @retval current transmit descriptor + */ +uint32_t emac_dma_poll_demand_get(emac_dma_tx_rx_type transfer_type) +{ + switch(transfer_type) + { + case EMAC_DMA_TRANSMIT: + { + return (EMAC_DMA->tpd_bit.tpd); + } + case EMAC_DMA_RECEIVE: + { + return (EMAC_DMA->rpd_bit.rpd); + } + } + return 0; +} + +/** + * @brief get receive dma process status + * @param none + * @retval every situation it describe in RM + * this parameter can be one of the following values: + * - EMAC_DMA_RX_RESET_STOP_COMMAND + * - EMAC_DMA_RX_FETCH_DESCRIPTOR + * - EMAC_DMA_RX_WAITING_PACKET + * - EMAC_DMA_RX_DESCRIPTOR_UNAVAILABLE + * - EMAC_DMA_RX_CLOSE_DESCRIPTOR + * - EMAC_DMA_RX_FIFO_TO_HOST + */ +emac_dma_receive_process_status_type emac_dma_receive_status_get(void) +{ + switch(EMAC_DMA->sts_bit.rs) + { + case EMAC_DMA_RX_RESET_STOP_COMMAND: + { + return EMAC_DMA_RX_RESET_STOP_COMMAND; + } + + case EMAC_DMA_RX_FETCH_DESCRIPTOR: + { + return EMAC_DMA_RX_FETCH_DESCRIPTOR; + } + + case EMAC_DMA_RX_WAITING_PACKET: + { + return EMAC_DMA_RX_WAITING_PACKET; + } + + case EMAC_DMA_RX_DESCRIPTOR_UNAVAILABLE: + { + return EMAC_DMA_RX_DESCRIPTOR_UNAVAILABLE; + } + + case EMAC_DMA_RX_CLOSE_DESCRIPTOR: + { + return EMAC_DMA_RX_CLOSE_DESCRIPTOR; + } + + case EMAC_DMA_RX_FIFO_TO_HOST: + { + return EMAC_DMA_RX_FIFO_TO_HOST; + } + } + + return EMAC_DMA_RX_RESET_STOP_COMMAND; +} + +/** + * @brief get transmit dma process status + * @param none + * @retval every situation it describe in RM + * this parameter can be one of the following values: + * - EMAC_DMA_TX_RESET_STOP_COMMAND + * - EMAC_DMA_TX_FETCH_DESCRIPTOR + * - EMAC_DMA_TX_WAITING_FOR_STATUS + * - EMAC_DMA_TX_HOST_TO_FIFO + * - EMAC_DMA_TX_DESCRIPTOR_UNAVAILABLE + * - EMAC_DMA_TX_CLOSE_DESCRIPTOR + */ +emac_dma_transmit_process_status_type emac_dma_transmit_status_get(void) +{ + switch(EMAC_DMA->sts_bit.ts) + { + case EMAC_DMA_TX_RESET_STOP_COMMAND: + { + return EMAC_DMA_TX_RESET_STOP_COMMAND; + } + + case EMAC_DMA_TX_FETCH_DESCRIPTOR: + { + return EMAC_DMA_TX_FETCH_DESCRIPTOR; + } + + case EMAC_DMA_TX_WAITING_FOR_STATUS: + { + return EMAC_DMA_TX_WAITING_FOR_STATUS; + } + + case EMAC_DMA_TX_HOST_TO_FIFO: + { + return EMAC_DMA_TX_HOST_TO_FIFO; + } + + case EMAC_DMA_TX_DESCRIPTOR_UNAVAILABLE: + { + return EMAC_DMA_TX_DESCRIPTOR_UNAVAILABLE; + } + + case EMAC_DMA_TX_CLOSE_DESCRIPTOR: + { + return EMAC_DMA_TX_CLOSE_DESCRIPTOR; + } + } + + return EMAC_DMA_TX_RESET_STOP_COMMAND; +} + +/** + * @brief set dma operations + * @param ops: operations of dma + * this parameter can be one of the following values: + * - EMAC_DMA_OPS_START_STOP_RECEIVE + * - EMAC_DMA_OPS_SECOND_FRAME + * - EMAC_DMA_OPS_FORWARD_UNDERSIZED + * - EMAC_DMA_OPS_FORWARD_ERROR + * - EMAC_DMA_OPS_START_STOP_TRANSMIT + * - EMAC_DMA_OPS_FLUSH_TRANSMIT_FIFO + * - EMAC_DMA_OPS_TRANSMIT_STORE_FORWARD + * - EMAC_DMA_OPS_RECEIVE_FLUSH_DISABLE + * - EMAC_DMA_OPS_RECEIVE_STORE_FORWARD + * - EMAC_DMA_OPS_DROP_ERROR_DISABLE + * @param new_state: TRUE or FALSE + * @retval none + */ +void emac_dma_operations_set(emac_dma_operations_type ops, confirm_state new_state) +{ + __IO uint32_t temp = 0; + switch(ops) + { + case EMAC_DMA_OPS_START_STOP_RECEIVE: + { + EMAC_DMA->opm_bit.ssr = new_state; + break; + } + + case EMAC_DMA_OPS_SECOND_FRAME: + { + EMAC_DMA->opm_bit.osf = new_state; + break; + } + + case EMAC_DMA_OPS_FORWARD_UNDERSIZED: + { + EMAC_DMA->opm_bit.fugf = new_state; + break; + } + + case EMAC_DMA_OPS_FORWARD_ERROR: + { + EMAC_DMA->opm_bit.fef = new_state; + break; + } + + case EMAC_DMA_OPS_START_STOP_TRANSMIT: + { + EMAC_DMA->opm_bit.sstc = new_state; + break; + } + + case EMAC_DMA_OPS_FLUSH_TRANSMIT_FIFO: + { + EMAC_DMA->opm_bit.ftf = new_state; + temp = EMAC_DMA->opm; + emac_delay(1); + EMAC_DMA->opm = temp; + break; + } + + case EMAC_DMA_OPS_TRANSMIT_STORE_FORWARD: + { + EMAC_DMA->opm_bit.tsf = new_state; + break; + } + + case EMAC_DMA_OPS_RECEIVE_FLUSH_DISABLE: + { + EMAC_DMA->opm_bit.dfrf = new_state; + break; + } + + case EMAC_DMA_OPS_RECEIVE_STORE_FORWARD: + { + EMAC_DMA->opm_bit.rsf = new_state; + break; + } + + case EMAC_DMA_OPS_DROP_ERROR_DISABLE: + { + EMAC_DMA->opm_bit.dt = new_state; + break; + } + } +} + +/** + * @brief set receive dma threshold + * @param value: receive threshold + * this parameter can be one of the following values: + * - EMAC_DMA_RX_THRESHOLD_64_BYTES + * - EMAC_DMA_RX_THRESHOLD_32_BYTES + * - EMAC_DMA_RX_THRESHOLD_96_BYTES + * - EMAC_DMA_RX_THRESHOLD_128_BYTES + * @retval none + */ +void emac_dma_receive_threshold_set(emac_dma_receive_threshold_type value) +{ + EMAC_DMA->opm_bit.rtc = value; +} + +/** + * @brief set transmit dma threshold + * @param value: transmit threshold + * this parameter can be one of the following values: + * - EMAC_DMA_TX_THRESHOLD_64_BYTES + * - EMAC_DMA_TX_THRESHOLD_128_BYTES + * - EMAC_DMA_TX_THRESHOLD_192_BYTES + * - EMAC_DMA_TX_THRESHOLD_256_BYTES + * - EMAC_DMA_TX_THRESHOLD_40_BYTES + * - EMAC_DMA_TX_THRESHOLD_32_BYTES + * - EMAC_DMA_TX_THRESHOLD_24_BYTES + * - EMAC_DMA_TX_THRESHOLD_16_BYTES + * @retval none + */ +void emac_dma_transmit_threshold_set(emac_dma_transmit_threshold_type value) +{ + EMAC_DMA->opm_bit.ttc = value; +} + +/** + * @brief enable dma interrupt + * @param it: interrupt type + * this parameter can be one of the following values: + * - EMAC_DMA_INTERRUPT_TX + * - EMAC_DMA_INTERRUPT_TX_STOP + * - EMAC_DMA_INTERRUPT_TX_UNAVAILABLE + * - EMAC_DMA_INTERRUPT_TX_JABBER + * - EMAC_DMA_INTERRUPT_RX_OVERFLOW + * - EMAC_DMA_INTERRUPT_TX_UNDERFLOW + * - EMAC_DMA_INTERRUPT_RX + * - EMAC_DMA_INTERRUPT_RX_UNAVAILABLE + * - EMAC_DMA_INTERRUPT_RX_STOP + * - EMAC_DMA_INTERRUPT_RX_TIMEOUT + * - EMAC_DMA_INTERRUPT_TX_EARLY + * - EMAC_DMA_INTERRUPT_FATAL_BUS_ERROR + * - EMAC_DMA_INTERRUPT_RX_EARLY + * - EMAC_DMA_INTERRUPT_ABNORMAL_SUMMARY + * - EMAC_DMA_INTERRUPT_NORMAL_SUMMARY + * @param new_state: TRUE or FALSE + * @retval none + */ +void emac_dma_interrupt_enable(emac_dma_interrupt_type it, confirm_state new_state) +{ + switch(it) + { + case EMAC_DMA_INTERRUPT_TX: + { + EMAC_DMA->ie_bit.tie = new_state; + break; + } + case EMAC_DMA_INTERRUPT_TX_STOP: + { + EMAC_DMA->ie_bit.tse = new_state; + break; + } + case EMAC_DMA_INTERRUPT_TX_UNAVAILABLE: + { + EMAC_DMA->ie_bit.tue = new_state; + break; + } + case EMAC_DMA_INTERRUPT_TX_JABBER: + { + EMAC_DMA->ie_bit.tje = new_state; + break; + } + case EMAC_DMA_INTERRUPT_RX_OVERFLOW: + { + EMAC_DMA->ie_bit.ove = new_state; + break; + } + case EMAC_DMA_INTERRUPT_TX_UNDERFLOW: + { + EMAC_DMA->ie_bit.une = new_state; + break; + } + case EMAC_DMA_INTERRUPT_RX: + { + EMAC_DMA->ie_bit.rie = new_state; + break; + } + case EMAC_DMA_INTERRUPT_RX_UNAVAILABLE: + { + EMAC_DMA->ie_bit.rbue = new_state; + break; + } + case EMAC_DMA_INTERRUPT_RX_STOP: + { + EMAC_DMA->ie_bit.rse = new_state; + break; + } + case EMAC_DMA_INTERRUPT_RX_TIMEOUT: + { + EMAC_DMA->ie_bit.rwte = new_state; + break; + } + case EMAC_DMA_INTERRUPT_TX_EARLY: + { + EMAC_DMA->ie_bit.eie = new_state; + break; + } + case EMAC_DMA_INTERRUPT_FATAL_BUS_ERROR: + { + EMAC_DMA->ie_bit.fbee = new_state; + break; + } + case EMAC_DMA_INTERRUPT_RX_EARLY: + { + EMAC_DMA->ie_bit.ere = new_state; + break; + } + case EMAC_DMA_INTERRUPT_ABNORMAL_SUMMARY: + { + EMAC_DMA->ie_bit.aie = new_state; + break; + } + case EMAC_DMA_INTERRUPT_NORMAL_SUMMARY: + { + EMAC_DMA->ie_bit.nie = new_state; + break; + } + } +} + +/** + * @brief get missed frames by the controller + * @param none + * @retval missed frames by the controller + */ +uint16_t emac_dma_controller_missing_frame_get(void) +{ + uint16_t number = EMAC_DMA->mfbocnt_bit.mfc; + return number; +} + +/** + * @brief get overflow bit for missed frame counter + * @param none + * @retval overflow bit for missed frame counter + */ +uint8_t emac_dma_missing_overflow_bit_get(void) +{ + uint8_t number = EMAC_DMA->mfbocnt_bit.obmfc; + return number; +} + +/** + * @brief get missed frames by the application + * @param none + * @retval missed frames by the application + */ +uint16_t emac_dma_application_missing_frame_get(void) +{ + uint16_t number = EMAC_DMA->mfbocnt_bit.ofc; + return number; +} + +/** + * @brief get overflow bit for FIFO overflow counter + * @param none + * @retval overflow bit for FIFO overflow counter + */ +uint8_t emac_dma_fifo_overflow_bit_get(void) +{ + uint8_t number = EMAC_DMA->mfbocnt_bit.obfoc; + return number; +} + +/** + * @brief get overflow bit for FIFO overflow counter + * @param transfer type: receive/transmit type + * this parameter can be one of the following values: + * - EMAC_DMA_TX_DESCRIPTOR + * - EMAC_DMA_RX_DESCRIPTOR + * - EMAC_DMA_TX_BUFFER + * - EMAC_DMA_RX_BUFFER + * @retval memory address + */ +uint32_t emac_dma_tansfer_address_get(emac_dma_transfer_address_type transfer_type) +{ + uint32_t address = 0; + + switch(transfer_type) + { + case EMAC_DMA_TX_DESCRIPTOR: + { + address = EMAC_DMA->ctd_bit.htdap; + break; + } + case EMAC_DMA_RX_DESCRIPTOR: + { + address = EMAC_DMA->crd_bit.hrdap; + break; + } + case EMAC_DMA_TX_BUFFER: + { + address = EMAC_DMA->ctbaddr_bit.htbap; + break; + } + case EMAC_DMA_RX_BUFFER: + { + address = EMAC_DMA->crbaddr_bit.hrbap; + break; + } + } + return address; +} + +/** + * @brief alternate dma descriptor size + * @param new_state: TRUE or FALSE + * @retval none + */ +void emac_dma_alternate_desc_size(confirm_state new_state) +{ + EMAC_DMA->bm_bit.atds = new_state; +} + +/** + * @brief reset all counter + * @param none + * @retval none + */ +void emac_mmc_counter_reset(void) +{ + EMAC_MMC->ctrl_bit.rc = TRUE; +} + +/** + * @brief counter stop counting from zero when it reaches maximum + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_mmc_rollover_stop(confirm_state new_state) +{ + EMAC_MMC->ctrl_bit.scr = new_state; +} + +/** + * @brief enable reset on read + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_mmc_reset_on_read_enable(confirm_state new_state) +{ + EMAC_MMC->ctrl_bit.rr = new_state; +} + +/** + * @brief freeze mmc counter + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_mmc_counter_freeze(confirm_state new_state) +{ + EMAC_MMC->ctrl_bit.fmc = new_state; +} + +/** + * @brief interupt status of received frames + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - MMC_RX_CRC_ERROR + * - MMC_RX_ALIGN_ERROR + * - MMC_RX_GOOD_UNICAST + * @retval the new state of usart_flag (SET or RESET). + */ +flag_status emac_mmc_received_status_get(uint32_t flag) +{ + if(EMAC_MMC->ri & flag) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief interupt status of transmit frames + * @param transmit_type: transmit type. + * this parameter can be one of the following values: + * - MMC_TX_SINGLE_COL + * - MMC_TX_MULTIPLE_COL + * - MMC_TX_GOOD_FRAMES + * @retval the new state of usart_flag (SET or RESET). + */ +flag_status emac_mmc_transmit_status_get(uint32_t flag) +{ + if(EMAC_MMC->ti & flag) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief mask received mmc interrupt + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - MMC_RX_CRC_ERROR + * - MMC_RX_ALIGN_ERROR + * - MMC_RX_GOOD_UNICAST + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_mmc_received_interrupt_mask_set(uint32_t flag, confirm_state new_state) +{ + switch(flag) + { + case MMC_RX_CRC_ERROR: + { + EMAC_MMC->rim_bit.rcefcim = new_state; + break; + } + case MMC_RX_ALIGN_ERROR: + { + EMAC_MMC->rim_bit.raefacim = new_state; + break; + } + case MMC_RX_GOOD_UNICAST: + { + EMAC_MMC->rim_bit.rugfcim = new_state; + break; + } + } +} + +/** + * @brief mask transmit mmc interrupt + * @param transmit_type: transmit type. + * this parameter can be one of the following values: + * - MMC_TX_SINGLE_COL + * - MMC_TX_MULTIPLE_COL + * - MMC_TX_GOOD_FRAMES + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_mmc_transmit_interrupt_mask_set(uint32_t flag, confirm_state new_state) +{ + switch(flag) + { + case MMC_TX_SINGLE_COL: + { + EMAC_MMC->tim_bit.tscgfcim = new_state; + break; + } + case MMC_TX_MULTIPLE_COL: + { + EMAC_MMC->tim_bit.tmcgfcim = new_state; + break; + } + case MMC_TX_GOOD_FRAMES: + { + EMAC_MMC->tim_bit.tgfcim = new_state; + break; + } + } +} + +/** + * @brief get good frame numbers as single collision occurs. + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - MMC_TX_SINGLE_COL + * - MMC_TX_MULTIPLE_COL + * - MMC_TX_GOOD_FRAMES + * @retval good frames + */ +uint32_t emac_mmc_transmit_good_frames_get(uint32_t flag) +{ + uint32_t good_frames = MMC_TX_GOOD_FRAMES; + + switch(flag) + { + case MMC_TX_SINGLE_COL: + { + good_frames = EMAC_MMC->tfscc_bit.tgfscc; + break; + } + case MMC_TX_MULTIPLE_COL: + { + good_frames = EMAC_MMC->tfmscc_bit.tgfmscc; + break; + } + case MMC_TX_GOOD_FRAMES: + { + good_frames = EMAC_MMC->tfcnt_bit.tgfc; + break; + } + } + return good_frames; +} + +/** + * @brief get good frame numbers as single collision occurs. + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - MMC_RX_CRC_ERROR + * - MMC_RX_ALIGN_ERROR + * - MMC_RX_GOOD_UNICAST + * @retval good frames + */ +uint32_t emac_mmc_received_error_frames_get(uint32_t flag) +{ + uint32_t error_frames = MMC_RX_GOOD_UNICAST; + + switch(flag) + { + case MMC_RX_CRC_ERROR: + { + error_frames = EMAC_MMC->rfcecnt_bit.rfcec; + break; + } + case MMC_RX_ALIGN_ERROR: + { + error_frames = EMAC_MMC->rfaecnt_bit.rfaec; + break; + } + case MMC_RX_GOOD_UNICAST: + { + error_frames = EMAC_MMC->rgufcnt_bit.rgufc; + break; + } + } + return error_frames; +} + +/** + * @brief enable timestamp. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_timestamp_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.te = new_state; +} + +/** + * @brief enable timestamp fine update. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_timestamp_fine_update_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.tfcu = new_state; +} + +/** + * @brief initialize timestamp time system. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_timestamp_system_time_init(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.ti = new_state; +} + +/** + * @brief update timestamp time system. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_timestamp_system_time_update(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.tu = new_state; +} + +/** + * @brief enable timestamp interrupt trigger. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_interrupt_trigger_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.tite = new_state; +} + +/** + * @brief update timestamp addend register. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_addend_register_update(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.aru = new_state; +} + +/** + * @brief enable timestamp snapshot for all received frames. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_snapshot_received_frames_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.etaf = new_state; +} + +/** + * @brief enable digital rollover. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_subsecond_rollover_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.tdbrc = new_state; +} + +/** + * @brief enable packet snooping for version 2. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_psv2_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.eppv2f = new_state; +} + +/** + * @brief enable snapshot over emac. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_snapshot_emac_frames_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.eppef = new_state; +} + +/** + * @brief enable snapshot for ipv6 frames. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_snapshot_ipv6_frames_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.eppfsip6u = new_state; +} + +/** + * @brief enable snapshot for ipv4 frames. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_snapshot_ipv4_frames_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.eppfsip4u = new_state; +} + +/** + * @brief enable snapshot for event message. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_snapshot_event_message_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.etsfem = new_state; +} + +/** + * @brief enable snapshot for message relevant to master + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_snapshot_master_event_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.esfmrtm = new_state; +} + +/** + * @brief set clock node type + * @param node: select ptp packets for taking snapshot + * this parameter can be one of the following values: + * - EMAC_PTP_NORMAL_CLOCK + * - EMAC_PTP_BOUNDARY_CLOCK + * - EMAC_PTP_END_TO_END_CLOCK + * - EMAC_PTP_PEER_TO_PEER_CLOCK + * @retval none + */ +void emac_ptp_clock_node_set(emac_ptp_clock_node_type node) +{ + EMAC_PTP->tsctrl_bit.sppfts = node; +} + +/** + * @brief enable ptp frame filtering mac address + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_mac_address_filter_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.emafpff = new_state; +} + +/** + * @brief check whether the specified emac ptp flag is set or not. + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - EMAC_PTP_TI_FLAG: time stamp initialized flag + * - EMAC_PTP_TU_FLAG: time stamp updtated flag + * - EMAC_PTP_ARU_FLAG: transmit data buffer empty flag + * @retval the new state of usart_flag (SET or RESET). + */ +flag_status emac_ptp_flag_get(uint32_t flag) +{ + if(EMAC_PTP->tsctrl & flag) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief set subsecond increment value + * @param value: add to subsecond value for every update + * @retval none + */ +void emac_ptp_subsecond_increment_set(uint8_t value) +{ + EMAC_PTP->ssinc_bit.ssiv = value; +} + +/** + * @brief get system time second + * @param none + * @retval system time second + */ +uint32_t emac_ptp_system_second_get(void) +{ + uint32_t second = EMAC_PTP->tsh_bit.ts; + return second; +} + +/** + * @brief get system time subsecond + * @param none + * @retval system time subsecond + */ +uint32_t emac_ptp_system_subsecond_get(void) +{ + uint32_t subsecond = EMAC_PTP->tsl_bit.tss; + return subsecond; +} + +/** + * @brief get system time sign + * @param none + * @retval TRUE or FALSE + */ +confirm_state emac_ptp_system_time_sign_get(void) +{ + if(EMAC_PTP->tsl_bit.ast) + { + return TRUE; + } + else + { + return FALSE; + } +} + +/** + * @brief set system time + * @param sign: plus or minus + * @param second: system time second + * @param subsecond: system time subsecond + * @retval none + */ +void emac_ptp_system_time_set(uint32_t sign, uint32_t second, uint32_t subsecond) +{ + EMAC_PTP->tslud_bit.ast = sign ? 1 : 0; + EMAC_PTP->tshud_bit.ts = second; + EMAC_PTP->tslud_bit.tss = subsecond; +} + +/** + * @brief set time stamp addend + * @param value: to achieve time synchronization + * @retval none + */ +void emac_ptp_timestamp_addend_set(uint32_t value) +{ + EMAC_PTP->tsad_bit.tar = value; +} + +/** + * @brief set target time stamp high + * @param value: to set target time second + * @retval none + */ +void emac_ptp_target_second_set(uint32_t value) +{ + EMAC_PTP->tth_bit.ttsr = value; +} + +/** + * @brief set target time stamp low + * @param value: to set target time nanosecond + * @retval none + */ +void emac_ptp_target_nanosecond_set(uint32_t value) +{ + EMAC_PTP->ttl_bit.ttlr = value; +} + +/** + * @brief set target time stamp low + * @param status: type of status + * this parameter can be one of the following values: + * - EMAC_PTP_SECOND_OVERFLOW + * - EMAC_PTP_TARGET_TIME_REACH + * @retval TRUE or FALSE + */ +confirm_state emac_ptp_timestamp_status_get(emac_ptp_timestamp_status_type status) +{ + switch(status) + { + case EMAC_PTP_SECOND_OVERFLOW: + { + if(EMAC_PTP->tssr_bit.tso) + { + return TRUE; + } + else + { + return FALSE; + } + } + case EMAC_PTP_TARGET_TIME_REACH: + { + if(EMAC_PTP->tssr_bit.tttr) + { + return TRUE; + } + else + { + return FALSE; + } + } + } + return FALSE; +} + +/** + * @brief set pps frequency + * @param freq: pps frequency + * this parameter can be one of the following values: + * - EMAC_PTP_PPS_1HZ + * - EMAC_PTP_PPS_2HZ + * - EMAC_PTP_PPS_4HZ + * - EMAC_PTP_PPS_8HZ + * - EMAC_PTP_PPS_16HZ + * - EMAC_PTP_PPS_32HZ + * - EMAC_PTP_PPS_64HZ + * - EMAC_PTP_PPS_128HZ + * - EMAC_PTP_PPS_256HZ + * - EMAC_PTP_PPS_512HZ + * - EMAC_PTP_PPS_1024HZ + * - EMAC_PTP_PPS_2048HZ + * - EMAC_PTP_PPS_4096HZ + * - EMAC_PTP_PPS_8192HZ + * - EMAC_PTP_PPS_16384HZ + * - EMAC_PTP_PPS_32768HZ + * @retval none + */ +void emac_ptp_pps_frequency_set(emac_ptp_pps_control_type freq) +{ + EMAC_PTP->ppscr_bit.pofc = freq; +} + +/** + * @brief this is delay function base on system clock. + * @param delay: delay time + * @retval none + */ +static void emac_delay(uint32_t delay) +{ + __IO uint32_t delay_time = delay * (system_core_clock / 8 / 1000); + do + { + __NOP(); + } + while(delay_time --); +} + +/** + * @brief check whether the specified emac dma flag is set or not. + * @param dma_flag: specifies the emac dma flag to check. + * this parameter can be one of emac dma flag status: + * - EMAC_DMA_TI_FLAG + * - EMAC_DMA_TPS_FLAG + * - EMAC_DMA_TBU_FLAG + * - EMAC_DMA_TJT_FLAG + * - EMAC_DMA_OVF_FLAG + * - EMAC_DMA_UNF_FLAG + * - EMAC_DMA_RI_FLAG + * - EMAC_DMA_RBU_FLAG + * - EMAC_DMA_RPS_FLAG + * - EMAC_DMA_RWT_FLAG + * - EMAC_DMA_ETI_FLAG + * - EMAC_DMA_FBEI_FLAG + * - EMAC_DMA_ERI_FLAG + * - EMAC_DMA_AIS_FLAG + * - EMAC_DMA_NIS_FLAG + * @retval the new state of dma_flag (SET or RESET). + */ +flag_status emac_dma_flag_get(uint32_t dma_flag) +{ + flag_status status = RESET; + + if(EMAC_DMA->sts & dma_flag) + status = SET; + /* return the new state (SET or RESET) */ + return status; +} + +/** + * @brief check whether the specified emac dma interrupt flag is set or not. + * @param dma_flag: specifies the emac dma flag to check. + * this parameter can be one of emac dma flag status: + * - EMAC_DMA_TI_FLAG + * - EMAC_DMA_TPS_FLAG + * - EMAC_DMA_TBU_FLAG + * - EMAC_DMA_TJT_FLAG + * - EMAC_DMA_OVF_FLAG + * - EMAC_DMA_UNF_FLAG + * - EMAC_DMA_RI_FLAG + * - EMAC_DMA_RBU_FLAG + * - EMAC_DMA_RPS_FLAG + * - EMAC_DMA_RWT_FLAG + * - EMAC_DMA_ETI_FLAG + * - EMAC_DMA_FBEI_FLAG + * - EMAC_DMA_ERI_FLAG + * - EMAC_DMA_AIS_FLAG + * - EMAC_DMA_NIS_FLAG + * @retval the new state of dma_flag (SET or RESET). + */ +flag_status emac_dma_interrupt_flag_get(uint32_t dma_flag) +{ + flag_status status = RESET; + switch(dma_flag) + { + case EMAC_DMA_TI_FLAG: + case EMAC_DMA_TBU_FLAG: + case EMAC_DMA_RI_FLAG: + case EMAC_DMA_ERI_FLAG: + if((EMAC_DMA->sts & dma_flag) && + (EMAC_DMA->ie & dma_flag) && + (EMAC_DMA->sts & EMAC_DMA_NIS_FLAG)) + status = SET; + break; + case EMAC_DMA_TPS_FLAG: + case EMAC_DMA_TJT_FLAG: + case EMAC_DMA_OVF_FLAG: + case EMAC_DMA_UNF_FLAG: + case EMAC_DMA_RBU_FLAG: + case EMAC_DMA_RPS_FLAG: + case EMAC_DMA_RWT_FLAG: + case EMAC_DMA_ETI_FLAG: + case EMAC_DMA_FBEI_FLAG: + if((EMAC_DMA->sts & dma_flag) && + (EMAC_DMA->ie & dma_flag) && + (EMAC_DMA->sts & EMAC_DMA_AIS_FLAG)) + status = SET; + break; + default: + break; + } + /* return the new state (SET or RESET) */ + return status; +} + +/** + * @brief clear the emac dma flag. + * @param dma_flag: specifies the emac dma flags to clear. + * this parameter can be any combination of the following values: + * - EMAC_DMA_TI_FLAG + * - EMAC_DMA_TPS_FLAG + * - EMAC_DMA_TBU_FLAG + * - EMAC_DMA_TJT_FLAG + * - EMAC_DMA_OVF_FLAG + * - EMAC_DMA_UNF_FLAG + * - EMAC_DMA_RI_FLAG + * - EMAC_DMA_RBU_FLAG + * - EMAC_DMA_RPS_FLAG + * - EMAC_DMA_RWT_FLAG + * - EMAC_DMA_ETI_FLAG + * - EMAC_DMA_FBEI_FLAG + * - EMAC_DMA_ERI_FLAG + * - EMAC_DMA_AIS_FLAG + * - EMAC_DMA_NIS_FLAG + * @retval none + */ +void emac_dma_flag_clear(uint32_t dma_flag) +{ + EMAC_DMA->sts = dma_flag; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +#endif + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f403a_407_rtc.c b/libraries/drivers/src/at32f403a_407_rtc.c new file mode 100644 index 0000000..1573b89 --- /dev/null +++ b/libraries/drivers/src/at32f403a_407_rtc.c @@ -0,0 +1,247 @@ +/** + ************************************************************************** + * @file at32f403a_407_rtc.c + * @brief contains all the functions for the rtc firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup RTC + * @brief RTC driver modules + * @{ + */ + +#ifdef RTC_MODULE_ENABLED + +/** @defgroup RTC_private_functions + * @{ + */ + +/** + * @brief rtc counter set + * @param counter_value (0x0000_0000 ~ 0xFFFF_FFFF) + * @retval none + */ +void rtc_counter_set(uint32_t counter_value) +{ + /* enter rtc config mode */ + RTC->ctrll = 0x003F; + + /* set rtc counter */ + RTC->cnth_bit.cnt = (uint16_t)(counter_value >> 16); + RTC->cntl_bit.cnt = (uint16_t)(counter_value & 0x0000FFFF); + + /* exit rtc config mode */ + RTC->ctrll = 0x000F; +} + +/** + * @brief rtc counter get + * @param none + * @retval rtc counter + */ +uint32_t rtc_counter_get(void) +{ + uint32_t cnt = 0; + + cnt = RTC->cnth; + cnt = (cnt << 16) | RTC->cntl; + + return cnt; +} + +/** + * @brief rtc divider set + * @param div_value (0x0000_0000 ~ 0x000F_FFFF) + * @retval none + */ +void rtc_divider_set(uint32_t div_value) +{ + /* enter rtc config mode */ + RTC->ctrll = 0x003F; + + /* set rtc divider */ + RTC->divh_bit.div = (uint16_t)(div_value >> 16); + RTC->divl_bit.div = (uint16_t)(div_value & 0x0000FFFF); + + /* exit rtc config mode */ + RTC->ctrll = 0x000F; +} + +/** + * @brief rtc divider get + * @param none + * @retval rtc counter + */ +uint32_t rtc_divider_get(void) +{ + uint32_t div = 0; + + div = RTC->divcnth; + div = (div << 16) | RTC->divcntl; + + return div; +} + +/** + * @brief rtc alarm value set + * @param alarm_value (0x0000_0000 ~ 0xFFFF_FFFF) + * @retval none + */ +void rtc_alarm_set(uint32_t alarm_value) +{ + /* enter rtc config mode */ + RTC->ctrll = 0x003F; + + /* set rtc alarm value */ + RTC->tah_bit.ta = (uint16_t)(alarm_value >> 16); + RTC->tal_bit.ta = (uint16_t)(alarm_value & 0x0000FFFF); + + /* exit rtc config mode */ + RTC->ctrll = 0x000F; +} + +/** + * @brief rtc interrupt enable + * @param source + * this parameter can be any combination of the following values: + * - RTC_TS_INT: time second interrupt. + * - RTC_TA_INT: time alarm interrupt. + * - RTC_OVF_INT: overflow interrupt. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void rtc_interrupt_enable(uint16_t source, confirm_state new_state) +{ + if(new_state == FALSE) + { + RTC->ctrlh &= ~source; + } + else + { + RTC->ctrlh |= source; + } +} + +/** + * @brief rtc flag get + * @param flag + * this parameter can be one of the following values: + * - RTC_TS_FLAG: time second flag. + * - RTC_TA_FLAG: time alarm flag. + * - RTC_OVF_FLAG: overflow flag. + * - RTC_UPDF_FLAG: rtc update finish flag. + * - RTC_CFGF_FLAG: rtc configuration finish flag. + * @retval state of rtc flag + */ +flag_status rtc_flag_get(uint16_t flag) +{ + flag_status status = RESET; + + if ((RTC->ctrll & flag) != (uint16_t)RESET) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @brief rtc interrupt flag get + * @param flag + * this parameter can be one of the following values: + * - RTC_TS_FLAG: time second flag. + * - RTC_TA_FLAG: time alarm flag. + * - RTC_OVF_FLAG: overflow flag. + * @retval state of rtc flag + */ +flag_status rtc_interrupt_flag_get(uint16_t flag) +{ + flag_status status = RESET; + + if (((RTC->ctrll & flag) != (uint16_t)RESET) && ((RTC->ctrlh & flag) != (uint16_t)RESET)) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @brief rtc flag clear + * @param interrupt_flag + * this parameter can be any combination of the following values: + * - RTC_TS_FLAG: time second flag. + * - RTC_TA_FLAG: time alarm flag. + * - RTC_OVF_FLAG: overflow flag. + * - RTC_UPDF_FLAG: rtc update finish flag. + * @retval none + */ +void rtc_flag_clear(uint16_t flag) +{ + RTC->ctrll = ~(flag | 0x10) | (RTC->ctrll_bit.cfgen << 4); +} + +/** + * @brief rtc wait configuration finish + * @param none + * @retval none + */ +void rtc_wait_config_finish(void) +{ + while (RTC->ctrll_bit.cfgf == 0); +} + +/** + * @brief rtc wait update finish + * @param none + * @retval none + */ +void rtc_wait_update_finish(void) +{ + while (RTC->ctrll_bit.updf == 0); +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f403a_407_sdio.c b/libraries/drivers/src/at32f403a_407_sdio.c new file mode 100644 index 0000000..55edf37 --- /dev/null +++ b/libraries/drivers/src/at32f403a_407_sdio.c @@ -0,0 +1,617 @@ +/** + ************************************************************************** + * @file at32f403a_407_sdio.c + * @brief contains all the functions for the sdio firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup SDIO + * @brief SDIO driver modules + * @{ + */ + +#ifdef SDIO_MODULE_ENABLED + +/** @defgroup SDIO_private_functions + * @{ + */ + +/** + * @brief reset the sdio register + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @retval none + */ +void sdio_reset(sdio_type *sdio_x) +{ + sdio_x->pwrctrl = 0x0; + sdio_x->clkctrl = 0x0; + sdio_x->argu = 0x0; + sdio_x->cmdctrl = 0x0; + sdio_x->dttmr = 0x0; + sdio_x->dtlen = 0x0; + sdio_x->dtctrl = 0x0; + sdio_x->inten = 0x0; + sdio_x->intclr = 0x004007FF; +} + +/** + * @brief set the power status of the controller + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param power_state + * this parameter can be one of the following values: + * - SDIO_POWER_OFF + * - SDIO_POWER_ON + * @retval none + */ +void sdio_power_set(sdio_type *sdio_x, sdio_power_state_type power_state) +{ + sdio_x->pwrctrl_bit.ps = power_state; +} + +/** + * @brief get power status. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @retval sdio_power_state_type (SDIO_POWER_ON or SDIO_POWER_OFF) + */ +sdio_power_state_type sdio_power_status_get(sdio_type *sdio_x) +{ + return (sdio_power_state_type)(sdio_x->pwrctrl_bit.ps); +} + +/** + * @brief config sdio clock + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param clk_div: sdio clock divide factor(frequency = sdio_clk / [clk_psc + 2]). + * @param clk_edg + * this parameter can be one of the following values: + * - SDIO_CLOCK_EDGE_RISING + * - SDIO_CLOCK_EDGE_FALLING + * @retval none + */ +void sdio_clock_config(sdio_type *sdio_x, uint16_t clk_div, sdio_edge_phase_type clk_edg) +{ + /* config clock edge */ + sdio_x->clkctrl_bit.clkegs = clk_edg; + + /* config clock divide [7:0] */ + sdio_x->clkctrl_bit.clkdiv_l = (clk_div & 0xFF); + + /* config clock divide [9:8] */ + sdio_x->clkctrl_bit.clkdiv_h = ((clk_div & 0x300) >> 8); +} + +/** + * @brief config sdio bus width + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param width + * this parameter can be one of the following values: + * - SDIO_BUS_WIDTH_D1 + * - SDIO_BUS_WIDTH_D4 + * - SDIO_BUS_WIDTH_D8 + * @retval none + */ +void sdio_bus_width_config(sdio_type *sdio_x, sdio_bus_width_type width) +{ + sdio_x->clkctrl_bit.busws = width; +} + +/** + * @brief enable or disable clock divider bypss + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_clock_bypass(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->clkctrl_bit.bypsen = new_state; +} + +/** + * @brief enable or disable power saving mode, config sdio_ck clock output + * when the bus is idle. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_power_saving_mode_enable(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->clkctrl_bit.pwrsven = new_state; +} + +/** + * @brief enable or disable hardware flow control. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_flow_control_enable(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->clkctrl_bit.hfcen = new_state; +} + +/** + * @brief enable or disable sdio_ck output. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_clock_enable(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->clkctrl_bit.clkoen = new_state; +} + +/** + * @brief enable or disable dma. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_dma_enable(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->dtctrl_bit.dmaen = new_state; +} + +/** + * @brief config corresponding interrupt. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param int_opt + * this parameter can be one of the following values: + * - SDIO_CMDFAIL_INT + * - SDIO_DTFAIL_INT + * - SDIO_CMDTIMEOUT_INT + * - SDIO_DTTIMEOUT_INT + * - SDIO_TXERRU_INT + * - SDIO_RXERRO_INT + * - SDIO_CMDRSPCMPL_INT + * - SDIO_CMDCMPL_INT + * - SDIO_DTCMP_INT + * - SDIO_SBITERR_INT + * - SDIO_DTBLKCMPL_INT + * - SDIO_DOCMD_INT + * - SDIO_DOTX_INT + * - SDIO_DORX_INT + * - SDIO_TXBUFH_INT + * - SDIO_RXBUFH_INT + * - SDIO_TXBUFF_INT + * - SDIO_RXBUFF_INT + * - SDIO_TXBUFE_INT + * - SDIO_RXBUFE_INT + * - SDIO_TXBUF_INT + * - SDIO_RXBUF_INT + * - SDIO_SDIOIF_INT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_interrupt_enable(sdio_type *sdio_x, uint32_t int_opt, confirm_state new_state) +{ + /* enable interrupt */ + if(TRUE == new_state) + { + sdio_x->inten |= int_opt; + } + /* disable interrupt */ + else + { + sdio_x->inten &= ~(int_opt); + } +} + +/** + * @brief get sdio interrupt flag. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param flag + * this parameter can be one of the following values: + * - SDIO_CMDFAIL_FLAG + * - SDIO_DTFAIL_FLAG + * - SDIO_CMDTIMEOUT_FLAG + * - SDIO_DTTIMEOUT_FLAG + * - SDIO_TXERRU_FLAG + * - SDIO_RXERRO_FLAG + * - SDIO_CMDRSPCMPL_FLAG + * - SDIO_CMDCMPL_FLAG + * - SDIO_DTCMPL_FLAG + * - SDIO_SBITERR_FLAG + * - SDIO_DTBLKCMPL_FLAG + * - SDIO_DOCMD_FLAG + * - SDIO_DOTX_FLAG + * - SDIO_DORX_FLAG + * - SDIO_TXBUFH_FLAG + * - SDIO_RXBUFH_FLAG + * - SDIO_TXBUFF_FLAG + * - SDIO_RXBUFF_FLAG + * - SDIO_TXBUFE_FLAG + * - SDIO_RXBUFE_FLAG + * - SDIO_TXBUF_FLAG + * - SDIO_RXBUF_FLAG + * - SDIO_SDIOIF_FLAG + * @retval flag_status (SET or RESET) + */ +flag_status sdio_interrupt_flag_get(sdio_type *sdio_x, uint32_t flag) +{ + flag_status status = RESET; + + if((sdio_x->inten & flag) && (sdio_x->sts & flag)) + { + status = SET; + } + + return status; +} + +/** + * @brief get sdio flag. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param flag + * this parameter can be one of the following values: + * - SDIO_CMDFAIL_FLAG + * - SDIO_DTFAIL_FLAG + * - SDIO_CMDTIMEOUT_FLAG + * - SDIO_DTTIMEOUT_FLAG + * - SDIO_TXERRU_FLAG + * - SDIO_RXERRO_FLAG + * - SDIO_CMDRSPCMPL_FLAG + * - SDIO_CMDCMPL_FLAG + * - SDIO_DTCMPL_FLAG + * - SDIO_SBITERR_FLAG + * - SDIO_DTBLKCMPL_FLAG + * - SDIO_DOCMD_FLAG + * - SDIO_DOTX_FLAG + * - SDIO_DORX_FLAG + * - SDIO_TXBUFH_FLAG + * - SDIO_RXBUFH_FLAG + * - SDIO_TXBUFF_FLAG + * - SDIO_RXBUFF_FLAG + * - SDIO_TXBUFE_FLAG + * - SDIO_RXBUFE_FLAG + * - SDIO_TXBUF_FLAG + * - SDIO_RXBUF_FLAG + * - SDIO_SDIOIF_FLAG + * @retval flag_status (SET or RESET) + */ +flag_status sdio_flag_get(sdio_type *sdio_x, uint32_t flag) +{ + flag_status status = RESET; + + if((sdio_x->sts & flag) == flag) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @brief clear sdio flag. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param int_opt + * this parameter can be any combination of the following values: + * - SDIO_CMDFAIL_FLAG + * - SDIO_DTFAIL_FLAG + * - SDIO_CMDTIMEOUT_FLAG + * - SDIO_DTTIMEOUT_FLAG + * - SDIO_TXERRU_FLAG + * - SDIO_RXERRO_FLAG + * - SDIO_CMDRSPCMPL_FLAG + * - SDIO_CMDCMPL_FLAG + * - SDIO_DTCMPL_FLAG + * - SDIO_SBITERR_FLAG + * - SDIO_DTBLKCMPL_FLAG + * - SDIO_SDIOIF_FLAG + * @retval none + */ +void sdio_flag_clear(sdio_type *sdio_x, uint32_t flag) +{ + sdio_x->intclr = flag; +} + +/** + * @brief config sdio command. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param command_struct : pointer to a sdio_command_struct_type structure + * that contains the configuration information for the sdio command. + * @retval none + */ +void sdio_command_config(sdio_type *sdio_x, sdio_command_struct_type *command_struct) +{ + /* disable command path state machine */ + sdio_x->cmdctrl_bit.ccsmen = FALSE; + + /* config command argument */ + sdio_x->argu = command_struct->argument; + + /* config command register */ + sdio_x->cmdctrl_bit.cmdidx = command_struct->cmd_index; + sdio_x->cmdctrl_bit.rspwt = command_struct->rsp_type; + sdio_x->cmdctrl_bit.intwt = (command_struct->wait_type & 0x1); /* [1:0] -> [0] */ + sdio_x->cmdctrl_bit.pndwt = (command_struct->wait_type & 0x2)>>1; /* [1:0] -> [1] */ +} + +/** + * @brief enable or disable command path state machine(CPSM). + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_command_state_machine_enable(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->cmdctrl_bit.ccsmen = new_state; +} + +/** + * @brief get command index of last command for which response received. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval uint8_t: command index + */ +uint8_t sdio_command_response_get(sdio_type *sdio_x) +{ + return sdio_x->rspcmd_bit.rspcmd; +} + +/** + * @brief get response received from the card for the last command. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param reg_index + * this parameter can be one of the following values: + * - SDIO_RSP1_INDEX + * - SDIO_RSP2_INDEX + * - SDIO_RSP3_INDEX + * - SDIO_RSP4_INDEX + * @retval uint32_t: response register value + */ +uint32_t sdio_response_get(sdio_type *sdio_x, sdio_rsp_index_type reg_index) +{ + uint32_t response_value = 0; + + switch(reg_index) + { + case SDIO_RSP1_INDEX: + response_value = sdio_x->rsp1; + break; + case SDIO_RSP2_INDEX: + response_value = sdio_x->rsp2; + break; + case SDIO_RSP3_INDEX: + response_value = sdio_x->rsp3; + break; + case SDIO_RSP4_INDEX: + response_value = sdio_x->rsp4; + break; + default: break; + } + + return response_value; +} + +/** + * @brief config sdio data. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param data_struct : pointer to a sdio_data_struct_type structure + * that contains the configuration information for the sdio data. + * @retval none + */ +void sdio_data_config(sdio_type *sdio_x, sdio_data_struct_type *data_struct) +{ + /* disable data path state machine */ + sdio_x->dtctrl_bit.tfren = FALSE; + + /* config data block, transfer mode and transfer direction */ + sdio_x->dtctrl_bit.blksize = data_struct->block_size; + sdio_x->dtctrl_bit.tfrdir = data_struct->transfer_direction; + sdio_x->dtctrl_bit.tfrmode = data_struct->transfer_mode; + + /* config data length */ + sdio_x->dtlen_bit.dtlen = data_struct->data_length; + + /* config data transfer timeout */ + sdio_x->dttmr_bit.timeout = data_struct->timeout; +} + +/** + * @brief enable or disable data path state machine(DPSM). + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_data_state_machine_enable(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->dtctrl_bit.tfren = new_state; +} + +/** + * @brief get the number of remaining data bytes to be transferred. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @retval uint32_t: number of bytes + */ +uint32_t sdio_data_counter_get(sdio_type *sdio_x) +{ + return sdio_x->dtcnt; +} + +/** + * @brief read a word data from sdio fifo. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @retval uint32_t: data received + */ +uint32_t sdio_data_read(sdio_type *sdio_x) +{ + return sdio_x->buf; +} + +/** + * @brief get the number of words left to be written to or read from fifo.. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @retval uint32_t: number of words + */ +uint32_t sdio_buffer_counter_get(sdio_type *sdio_x) +{ + return sdio_x->bufcnt; +} + +/** + * @brief write one word data to fifo. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param data: data to be transferred. + * @retval none + */ +void sdio_data_write(sdio_type *sdio_x, uint32_t data) +{ + sdio_x->buf = data; +} + +/** + * @brief set the read wait mode. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param mode + * this parameter can be one of the following values: + * - SDIO_READ_WAIT_CONTROLLED_BY_D2 + * - SDIO_READ_WAIT_CONTROLLED_BY_CK + * @retval none + */ +void sdio_read_wait_mode_set(sdio_type *sdio_x, sdio_read_wait_mode_type mode) +{ + sdio_x->dtctrl_bit.rdwtmode = mode; +} + +/** + * @brief enable or disable to start sd i/o read wait operation. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_read_wait_start(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->dtctrl_bit.rdwtstart = new_state; +} + +/** + * @brief enable or disable to stop sd i/o read wait operation. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_read_wait_stop(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->dtctrl_bit.rdwtstop = new_state; +} + +/** + * @brief enable or disable the sd i/o function. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_io_function_enable(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->dtctrl_bit.ioen = new_state; +} + +/** + * @brief enable or disable sd i/o suspend command sending. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_io_suspend_command_set(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->cmdctrl_bit.iosusp = new_state; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f403a_407_spi.c b/libraries/drivers/src/at32f403a_407_spi.c new file mode 100644 index 0000000..0840440 --- /dev/null +++ b/libraries/drivers/src/at32f403a_407_spi.c @@ -0,0 +1,677 @@ +/** + ************************************************************************** + * @file at32f403a_407_spi.c + * @brief contains all the functions for the spi firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup SPI + * @brief SPI driver modules + * @{ + */ + +#ifdef SPI_MODULE_ENABLED + +/** @defgroup SPI_private_functions + * @{ + */ + +/** + * @brief spi reset by crm reset register + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @retval none + */ +void spi_i2s_reset(spi_type *spi_x) +{ + if(spi_x == SPI1) + { + crm_periph_reset(CRM_SPI1_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_SPI1_PERIPH_RESET, FALSE); + } + else if(spi_x == SPI2) + { + crm_periph_reset(CRM_SPI2_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_SPI2_PERIPH_RESET, FALSE); + } + else if(spi_x == SPI3) + { + crm_periph_reset(CRM_SPI3_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_SPI3_PERIPH_RESET, FALSE); + } + else if(spi_x == SPI4) + { + crm_periph_reset(CRM_SPI4_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_SPI4_PERIPH_RESET, FALSE); + } +} + +/** + * @brief spi init config with its default value. + * @param spi_init_struct : pointer to a spi_init_type structure which will + * be initialized. + * @retval none + */ +void spi_default_para_init(spi_init_type* spi_init_struct) +{ + spi_init_struct->transmission_mode = SPI_TRANSMIT_FULL_DUPLEX; + spi_init_struct->master_slave_mode = SPI_MODE_SLAVE; + spi_init_struct->mclk_freq_division = SPI_MCLK_DIV_2; + spi_init_struct->first_bit_transmission = SPI_FIRST_BIT_MSB; + spi_init_struct->frame_bit_num = SPI_FRAME_8BIT; + spi_init_struct->clock_polarity = SPI_CLOCK_POLARITY_LOW; + spi_init_struct->clock_phase = SPI_CLOCK_PHASE_1EDGE; + spi_init_struct->cs_mode_selection = SPI_CS_SOFTWARE_MODE; +} + +/** + * @brief spi init config with its setting value. + * @param spi_init_struct : pointer to a spi_init_type structure which will be initialized. + * @retval none + */ +void spi_init(spi_type* spi_x, spi_init_type* spi_init_struct) +{ + spi_x->i2sctrl_bit.i2smsel = FALSE; + if(spi_init_struct->transmission_mode == SPI_TRANSMIT_FULL_DUPLEX) + { + spi_x->ctrl1_bit.slben = FALSE; + spi_x->ctrl1_bit.slbtd = FALSE; + spi_x->ctrl1_bit.ora = FALSE; + } + else if(spi_init_struct->transmission_mode == SPI_TRANSMIT_SIMPLEX_RX) + { + spi_x->ctrl1_bit.slben = FALSE; + spi_x->ctrl1_bit.slbtd = FALSE; + spi_x->ctrl1_bit.ora = TRUE; + } + else if(spi_init_struct->transmission_mode == SPI_TRANSMIT_HALF_DUPLEX_RX) + { + spi_x->ctrl1_bit.slben = TRUE; + spi_x->ctrl1_bit.slbtd = FALSE; + spi_x->ctrl1_bit.ora = FALSE; + } + else if(spi_init_struct->transmission_mode == SPI_TRANSMIT_HALF_DUPLEX_TX) + { + spi_x->ctrl1_bit.slben = TRUE; + spi_x->ctrl1_bit.slbtd = TRUE; + spi_x->ctrl1_bit.ora = FALSE; + } + + spi_x->ctrl1_bit.swcsen = spi_init_struct->cs_mode_selection; + if((spi_init_struct->master_slave_mode == SPI_MODE_MASTER) && (spi_init_struct->cs_mode_selection == SPI_CS_SOFTWARE_MODE)) + { + spi_x->ctrl1_bit.swcsil = TRUE; + } + else + { + spi_x->ctrl1_bit.swcsil = FALSE; + } + spi_x->ctrl1_bit.msten = spi_init_struct->master_slave_mode; + if(spi_init_struct->mclk_freq_division > SPI_MCLK_DIV_256) + { + spi_x->ctrl2_bit.mdiv_h = 1; + spi_x->ctrl1_bit.mdiv_l = spi_init_struct->mclk_freq_division & 0x7; + } + else + { + spi_x->ctrl2_bit.mdiv_h = 0; + spi_x->ctrl1_bit.mdiv_l = spi_init_struct->mclk_freq_division; + } + spi_x->ctrl1_bit.ltf = spi_init_struct->first_bit_transmission; + spi_x->ctrl1_bit.fbn = spi_init_struct->frame_bit_num; + spi_x->ctrl1_bit.clkpol = spi_init_struct->clock_polarity; + spi_x->ctrl1_bit.clkpha = spi_init_struct->clock_phase; +} + +/** + * @brief spi next transmit crc for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @retval none + */ +void spi_crc_next_transmit(spi_type* spi_x) +{ + spi_x->ctrl1_bit.ntc = TRUE; +} + +/** + * @brief set the crc polynomial value for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param crc_poly: crc polynomial value. + * @retval none + */ +void spi_crc_polynomial_set(spi_type* spi_x, uint16_t crc_poly) +{ + spi_x->cpoly_bit.cpoly = crc_poly; +} + +/** + * @brief return the crc polynomial register value for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @retval the select crc polynomial register value + */ +uint16_t spi_crc_polynomial_get(spi_type* spi_x) +{ + return spi_x->cpoly_bit.cpoly; +} + +/** + * @brief enable or disable the hardware crc calculation for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param new_state: new state of crc calculation. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void spi_crc_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->ctrl1_bit.ccen = new_state; +} + +/** + * @brief return the transmit or the receive crc value for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param crc_direction: select transmit or receive crc value to be read + * - SPI_CRC_RX + * - SPI_CRC_TX + * @retval the select crc register value + */ +uint16_t spi_crc_value_get(spi_type* spi_x, spi_crc_direction_type crc_direction) +{ + if(crc_direction == SPI_CRC_RX) + return spi_x->rcrc_bit.rcrc; + else + return spi_x->tcrc_bit.tcrc; +} + +/** + * @brief enable or disable the hardware cs output for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param new_state: new state of spi master cs output. + * this parameter can be: TRUE or FALSE. + * note:the bit only use in spi master mode + * @retval none + */ +void spi_hardware_cs_output_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->ctrl2_bit.hwcsoe = new_state; +} + +/** + * @brief set the software cs internal level for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param level: set the state of spi cs level. + * this parameter can be one of the following values: + * - SPI_SWCS_INTERNAL_LEVEL_LOW + * - SPI_SWCS_INTERNAL_LEVEL_HIGHT + * note:the bit only use when swcsen bit is set. + * note:when use this bit,io operation on the cs pin are invalid. + * @retval none + */ +void spi_software_cs_internal_level_set(spi_type* spi_x, spi_software_cs_level_type level) +{ + spi_x->ctrl1_bit.swcsil = level; +} + +/** + * @brief set the data frame bit num for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param bit_num: set the data frame size + * - SPI_FRAME_8BIT + * - SPI_FRAME_16BIT + * @retval none + */ +void spi_frame_bit_num_set(spi_type* spi_x, spi_frame_bit_num_type bit_num) +{ + spi_x->ctrl1_bit.fbn = bit_num; +} + +/** + * @brief set the data transmission direction in single line bidirectiona half duplex mode of the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param direction: data transfer direction + * this parameter can be one of the following values: + * - SPI_HALF_DUPLEX_DIRECTION_RX + * - SPI_HALF_DUPLEX_DIRECTION_TX + * @retval none + */ +void spi_half_duplex_direction_set(spi_type* spi_x, spi_half_duplex_direction_type direction) +{ + spi_x->ctrl1_bit.slbtd = direction; +} + +/** + * @brief enable or disable spi. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param new_state: new state of spi. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void spi_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->ctrl1_bit.spien = new_state; +} + +/** + * @brief i2s init config with its default value. + * @param i2s_init_struct : pointer to a i2s_init_type structure which will + * be initialized. + * @retval none + */ +void i2s_default_para_init(i2s_init_type* i2s_init_struct) +{ + i2s_init_struct->operation_mode = I2S_MODE_SLAVE_TX; + i2s_init_struct->audio_protocol = I2S_AUDIO_PROTOCOL_PHILLIPS; + i2s_init_struct->audio_sampling_freq = I2S_AUDIO_FREQUENCY_DEFAULT; + i2s_init_struct->data_channel_format = I2S_DATA_16BIT_CHANNEL_16BIT; + i2s_init_struct->clock_polarity = I2S_CLOCK_POLARITY_LOW; + i2s_init_struct->mclk_output_enable = FALSE; +} + +/** + * @brief i2s init config with its setting value. + * @param i2s_init_struct : pointer to a i2s_init_type structure which will be initialized. + * @retval none + */ +void i2s_init(spi_type* spi_x, i2s_init_type* i2s_init_struct) +{ + crm_clocks_freq_type clocks_freq; + uint32_t i2s_sclk_index = 0; + uint32_t i2sdiv_index = 2, i2sodd_index = 0, frequency_index = 0; + + /* i2s audio frequency config */ + if(i2s_init_struct->audio_sampling_freq == I2S_AUDIO_FREQUENCY_DEFAULT) + { + i2sodd_index = 0; + i2sdiv_index = 2; + } + else + { + crm_clocks_freq_get(&clocks_freq); + i2s_sclk_index = clocks_freq.sclk_freq; + if((i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PCM_SHORT) || (i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PCM_LONG)) + { + if(i2s_init_struct->mclk_output_enable == TRUE) + { + frequency_index = (((i2s_sclk_index / 128) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + } + else + { + if(i2s_init_struct->data_channel_format == I2S_DATA_16BIT_CHANNEL_16BIT) + frequency_index = (((i2s_sclk_index / 16) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + else + frequency_index = (((i2s_sclk_index / 32) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + } + } + else + { + if(i2s_init_struct->mclk_output_enable == TRUE) + { + frequency_index = (((i2s_sclk_index / 256) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + } + else + { + if(i2s_init_struct->data_channel_format == I2S_DATA_16BIT_CHANNEL_16BIT) + frequency_index = (((i2s_sclk_index / 32) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + else + frequency_index = (((i2s_sclk_index / 64) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + } + } + } + frequency_index = frequency_index / 10; + i2sodd_index = frequency_index & (uint16_t)0x0001; + i2sdiv_index = (frequency_index - i2sodd_index) / 2; + if((i2sdiv_index < 2) || (i2sdiv_index > 0x03FF)) + { + i2sodd_index = 0; + i2sdiv_index = 2; + } + spi_x->i2sclk_bit.i2sodd = i2sodd_index; + if(i2sdiv_index > 0x00FF) + { + spi_x->i2sclk_bit.i2sdiv_h = (i2sdiv_index >> 8) & 0x0003; + spi_x->i2sclk_bit.i2sdiv_l = i2sdiv_index & 0x00FF; + } + else + { + spi_x->i2sclk_bit.i2sdiv_h = 0; + spi_x->i2sclk_bit.i2sdiv_l = i2sdiv_index; + } + + /* i2s audio_protocol set*/ + if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PCM_LONG) + { + spi_x->i2sctrl_bit.pcmfssel = 1; + spi_x->i2sctrl_bit.stdsel = 3; + } + else if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PCM_SHORT) + { + spi_x->i2sctrl_bit.pcmfssel = 0; + spi_x->i2sctrl_bit.stdsel = 3; + } + else if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_LSB) + { + spi_x->i2sctrl_bit.pcmfssel = 0; + spi_x->i2sctrl_bit.stdsel = 2; + } + else if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_MSB) + { + spi_x->i2sctrl_bit.pcmfssel = 0; + spi_x->i2sctrl_bit.stdsel = 1; + } + else if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PHILLIPS) + { + spi_x->i2sctrl_bit.pcmfssel = 0; + spi_x->i2sctrl_bit.stdsel = 0; + } + + /* i2s data_channel_format set*/ + if(i2s_init_struct->data_channel_format == I2S_DATA_16BIT_CHANNEL_16BIT) + { + spi_x->i2sctrl_bit.i2scbn = 0; + spi_x->i2sctrl_bit.i2sdbn = 0; + } + else if(i2s_init_struct->data_channel_format == I2S_DATA_16BIT_CHANNEL_32BIT) + { + spi_x->i2sctrl_bit.i2scbn = 1; + spi_x->i2sctrl_bit.i2sdbn = 0; + } + else if(i2s_init_struct->data_channel_format == I2S_DATA_24BIT_CHANNEL_32BIT) + { + spi_x->i2sctrl_bit.i2scbn = 1; + spi_x->i2sctrl_bit.i2sdbn = 1; + } + else if(i2s_init_struct->data_channel_format == I2S_DATA_32BIT_CHANNEL_32BIT) + { + spi_x->i2sctrl_bit.i2scbn = 1; + spi_x->i2sctrl_bit.i2sdbn = 2; + } + + spi_x->i2sctrl_bit.i2sclkpol = i2s_init_struct->clock_polarity; + spi_x->i2sclk_bit.i2smclkoe = i2s_init_struct->mclk_output_enable; + spi_x->i2sctrl_bit.opersel = i2s_init_struct->operation_mode; + spi_x->i2sctrl_bit.i2smsel = TRUE; +} + +/** + * @brief enable or disable i2s. + * @param spi_x: select the i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4, I2S2EXT, I2S3EXT + * @param new_state: new state of i2s. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void i2s_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->i2sctrl_bit.i2sen = new_state; +} + +/** + * @brief enable or disable the specified spi/i2s interrupts. + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4, I2S2EXT, I2S3EXT + * @param spi_i2s_int: specifies the spi/i2s interrupt sources to be enabled or disabled. + * this parameter can be one of the following values: + * - SPI_I2S_ERROR_INT + * - SPI_I2S_RDBF_INT + * - SPI_I2S_TDBE_INT + * @param new_state: new state of the specified spi/i2s interrupts. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void spi_i2s_interrupt_enable(spi_type* spi_x, uint32_t spi_i2s_int, confirm_state new_state) +{ + if(new_state != FALSE) + { + spi_x->ctrl2 |= spi_i2s_int; + } + else + { + spi_x->ctrl2 &= ~spi_i2s_int; + } +} + +/** + * @brief enable or disable the spi/i2s dma transmitter mode. + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4, I2S2EXT, I2S3EXT + * @param new_state: new state of the dma request. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void spi_i2s_dma_transmitter_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->ctrl2_bit.dmaten = new_state; +} + +/** + * @brief enable or disable the spi/i2s dma receiver mode. + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4, I2S2EXT, I2S3EXT + * @param new_state: new state of the dma request. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void spi_i2s_dma_receiver_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->ctrl2_bit.dmaren = new_state; +} + +/** + * @brief spi/i2s data transmit + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4, I2S2EXT, I2S3EXT + * @param tx_data: the data to be transmit. + * this parameter can be: + * - (0x0000~0xFFFF) + * @retval none + */ +void spi_i2s_data_transmit(spi_type* spi_x, uint16_t tx_data) +{ + spi_x->dt = tx_data; +} + +/** + * @brief spi/i2s data receive + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4, I2S2EXT, I2S3EXT + * @retval the received data value + */ +uint16_t spi_i2s_data_receive(spi_type* spi_x) +{ + return (uint16_t)spi_x->dt; +} + +/** + * @brief get flag of the specified spi/i2s peripheral. + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4, I2S2EXT, I2S3EXT + * @param spi_i2s_flag: select the spi/i2s flag + * this parameter can be one of the following values: + * - SPI_I2S_RDBF_FLAG + * - SPI_I2S_TDBE_FLAG + * - I2S_ACS_FLAG (this flag only use in i2s mode) + * - I2S_TUERR_FLAG (this flag only use in i2s mode) + * - SPI_CCERR_FLAG (this flag only use in spi mode) + * - SPI_MMERR_FLAG (this flag only use in spi mode) + * - SPI_I2S_ROERR_FLAG + * - SPI_I2S_BF_FLAG + * @retval the new state of spi/i2s flag + */ +flag_status spi_i2s_flag_get(spi_type* spi_x, uint32_t spi_i2s_flag) +{ + flag_status status = RESET; + if ((spi_x->sts & spi_i2s_flag) == RESET) + { + status = RESET; + } + else + { + status = SET; + } + return status; +} + +/** + * @brief get interrupt flag of the specified spi/i2s peripheral. + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4, I2S2EXT, I2S3EXT + * @param spi_i2s_flag: select the spi/i2s flag + * this parameter can be one of the following values: + * - SPI_I2S_RDBF_FLAG + * - SPI_I2S_TDBE_FLAG + * - I2S_TUERR_FLAG (this flag only use in i2s mode) + * - SPI_CCERR_FLAG (this flag only use in spi mode) + * - SPI_MMERR_FLAG (this flag only use in spi mode) + * - SPI_I2S_ROERR_FLAG + * @retval the new state of spi/i2s flag + */ +flag_status spi_i2s_interrupt_flag_get(spi_type* spi_x, uint32_t spi_i2s_flag) +{ + flag_status status = RESET; + + switch(spi_i2s_flag) + { + case SPI_I2S_RDBF_FLAG: + if(spi_x->sts_bit.rdbf && spi_x->ctrl2_bit.rdbfie) + { + status = SET; + } + break; + case SPI_I2S_TDBE_FLAG: + if(spi_x->sts_bit.tdbe && spi_x->ctrl2_bit.tdbeie) + { + status = SET; + } + break; + case I2S_TUERR_FLAG: + if(spi_x->sts_bit.tuerr && spi_x->ctrl2_bit.errie) + { + status = SET; + } + break; + case SPI_CCERR_FLAG: + if(spi_x->sts_bit.ccerr && spi_x->ctrl2_bit.errie) + { + status = SET; + } + break; + case SPI_MMERR_FLAG: + if(spi_x->sts_bit.mmerr && spi_x->ctrl2_bit.errie) + { + status = SET; + } + break; + case SPI_I2S_ROERR_FLAG: + if(spi_x->sts_bit.roerr && spi_x->ctrl2_bit.errie) + { + status = SET; + } + break; + default: + break; + }; + return status; +} + +/** + * @brief clear flag of the specified spi/i2s peripheral. + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4, I2S2EXT, I2S3EXT + * @param spi_i2s_flag: select the spi/i2s flag + * this parameter can be one of the following values: + * - SPI_CCERR_FLAG + * - SPI_I2S_RDBF_FLAG + * - I2S_TUERR_FLAG + * - SPI_MMERR_FLAG + * - SPI_I2S_ROERR_FLAG + * @note + * SPI_I2S_TDBE_FLAG this flag is cleared when the tx buffer already contain data to be transmit. + * I2S_ACS_FLAG this flag cann't cleared by software,the flag indicate the channel side(not use in pcm standard mode). + * SPI_I2S_BF_FLAG this flag cann't cleared by software, it's set and cleared by hardware. + * @retval none + */ +void spi_i2s_flag_clear(spi_type* spi_x, uint32_t spi_i2s_flag) +{ + if(spi_i2s_flag == SPI_CCERR_FLAG) + spi_x->sts = ~SPI_CCERR_FLAG; + else if(spi_i2s_flag == SPI_I2S_RDBF_FLAG) + UNUSED(spi_x->dt); + else if(spi_i2s_flag == I2S_TUERR_FLAG) + UNUSED(spi_x->sts); + else if(spi_i2s_flag == SPI_MMERR_FLAG) + { + UNUSED(spi_x->sts); + spi_x->ctrl1 = spi_x->ctrl1; + } + else if(spi_i2s_flag == SPI_I2S_ROERR_FLAG) + { + UNUSED(spi_x->dt); + UNUSED(spi_x->sts); + } +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f403a_407_usb.c b/libraries/drivers/src/at32f403a_407_usb.c new file mode 100644 index 0000000..67cdd64 --- /dev/null +++ b/libraries/drivers/src/at32f403a_407_usb.c @@ -0,0 +1,597 @@ +/** + ************************************************************************** + * @file at32f403a_407_usb.c + * @brief contains the functions for the usb firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup USB + * @brief USB driver modules + * @{ + */ + +#include "at32f403a_407_conf.h" + + +#ifdef USB_MODULE_ENABLED + +/** @defgroup USB_private_functions + * @{ + */ + +/** + * @brief usb packet buffer start address + */ +#define USB_ENDP_DESC_TABLE_OFFSET 0x40 +uint32_t g_usb_packet_address = USB_PACKET_BUFFER_ADDRESS; +static uint16_t g_usb_offset_addr = USB_ENDP_DESC_TABLE_OFFSET; + +/** + * @brief initialize usb peripheral controller register + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @retval none + */ +void usb_dev_init(usbd_type *usbx) +{ + /* clear usb core reset */ + usbx->ctrl_bit.csrst = 0; + + /* clear usb interrupt status */ + usbx->intsts = 0; + + /* set usb packet buffer descirption table address */ + usbx->buftbl = USB_BUFFER_TABLE_ADDRESS; + + /* enable usb core and set device address to 0 */ + usbx->devaddr = 0x80; + + usb_interrupt_enable(usbx, USB_SOF_INT | USB_RST_INT | USB_SP_INT | USB_WK_INT | USB_TC_INT, TRUE); +} + +/** + * @brief connect usb device + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @retval none + */ +void usb_connect(usbd_type *usbx) +{ + /* enable usb phy */ + usbx->ctrl_bit.disusb = 0; + + /* Dp 1.5k pull-up enable */ + usbx->cfg_bit.puo = 0; +} + +/** + * @brief disconnect usb device + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @retval none + */ +void usb_disconnect(usbd_type *usbx) +{ + /* disable usb phy */ + usbx->ctrl_bit.disusb = TRUE; + + /* D+ 1.5k pull-up disable */ + usbx->cfg_bit.puo = TRUE; +} + + +/** + * @brief mapping usb packet buffer area + * two mapping intervals are available for packet buffer area, + * and are select by the usbbufs in the crm misc1 register. + * when usbbufs is 0,sram size is 512 bytes, packet buffer start + * address is 0x40006000.when usbbufs is 1, sram size is fixed to + * 768~1280 bytes, and the packet buffer start address is fixed to + * 0x40007800,packet buffer size decided by whether can1 and can2 are + * enabled;when both can1 and can2 are disabled, usb packet buffer can be set to the + * maximum of 1280 bytes; when either can1 or can2 is enabled, usb packet buffer can be set to the + * maximum of 1024 bytes; when both CAN1 and CAN2 are enabled, usb packet buffer can be set to the + * maximum of 768 bytes. + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @retval none + */ +void usb_usbbufs_enable(usbd_type *usbx, confirm_state state) +{ + if(state == TRUE) + { + /* enable usbbufs */ + g_usb_packet_address = USB_PACKET_BUFFER_ADDRESS_EX; + CRM->misc1_bit.usbbufs = TRUE; + } + else + { + /* disable usbbufs */ + g_usb_packet_address = USB_PACKET_BUFFER_ADDRESS; + CRM->misc1_bit.usbbufs = FALSE; + } + UNUSED(usbx); +} + +/** + * @brief open usb endpoint + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @param ept_info: endpoint information structure + * @retval none + */ +void usb_ept_open(usbd_type *usbx, usb_ept_info *ept_info) +{ + uint16_t type = 0; + + /* set endpoint address */ + USB_SET_EPT_ADDRESS(ept_info->eptn, ept_info->ept_address); + + /* select endpoint transfer type */ + if(ept_info->trans_type == EPT_CONTROL_TYPE) + { + type = USB_EPT_CONTROL; + } + else if(ept_info->trans_type == EPT_BULK_TYPE) + { + type = USB_EPT_BULK; + } + else if(ept_info->trans_type == EPT_INT_TYPE) + { + type = USB_EPT_INT; + } + else if(ept_info->trans_type == EPT_ISO_TYPE) + { + type = USB_EPT_ISO; + ept_info->is_double_buffer = TRUE; + } + + /* configure endpoint transfer type (control, bulk, interrupt, isochronous) */ + USB_SET_TRANS_TYPE(ept_info->eptn, type); + + /* endpoint is in transfer */ + if(ept_info->inout == DATA_TRANS_IN) + { + if(ept_info->is_double_buffer == 0) + { + /* set in endpoint tx offset address */ + USB_SET_TX_ADDRESS(ept_info->eptn, ept_info->tx_addr); + + /* clear in endpoint data toggle */ + USB_CLEAR_TXDTS(ept_info->eptn); + + /* set endpoint transmission status: nak */ + USB_SET_TXSTS(ept_info->eptn, USB_TX_NAK); + } + else + { + /* set double buffer endpoint*/ + USB_SET_EPT_DOUBLE_BUFFER(ept_info->eptn); + + /* set in endpoint offset address0 and address1 */ + USB_SET_DOUBLE_BUFF0_ADDRESS(ept_info->eptn, ept_info->tx_addr); + USB_SET_DOUBLE_BUFF1_ADDRESS(ept_info->eptn, ept_info->rx_addr); + + /* clear in and out data toggle */ + USB_CLEAR_TXDTS(ept_info->eptn); + USB_CLEAR_RXDTS(ept_info->eptn); + + /* toggle rx data toggle flag */ + USB_TOGGLE_RXDTS(ept_info->eptn); + + /* set endpoint reception status: disable */ + USB_SET_RXSTS(ept_info->eptn, USB_RX_DISABLE); + + /* set endpoint transmision status: nak */ + USB_SET_TXSTS(ept_info->eptn, USB_TX_NAK); + } + } + else + { + if(ept_info->is_double_buffer == 0) + { + /* set out endpoint rx offset address */ + USB_SET_RX_ADDRESS(ept_info->eptn, ept_info->rx_addr); + + /* clear out endpoint data toggle */ + USB_CLEAR_RXDTS(ept_info->eptn); + + /* set out endpoint max reception buffer size */ + USB_SET_RXLEN(ept_info->eptn, ept_info->maxpacket); + + /* set endpoint reception status: valid */ + USB_SET_RXSTS(ept_info->eptn, USB_RX_VALID); + } + else + { + /* set double buffer endpoint */ + USB_SET_EPT_DOUBLE_BUFFER(ept_info->eptn); + + /* set out endpoint offset address0 and address1 */ + USB_SET_DOUBLE_BUFF0_ADDRESS(ept_info->eptn, ept_info->tx_addr); + USB_SET_DOUBLE_BUFF1_ADDRESS(ept_info->eptn, ept_info->rx_addr); + + /* set out endpoint max reception buffer size */ + USB_SET_EPT_DOUBLE_BUF0_LEN(ept_info->eptn, ept_info->maxpacket, DATA_TRANS_OUT); + USB_SET_EPT_DOUBLE_BUF1_LEN(ept_info->eptn, ept_info->maxpacket, DATA_TRANS_OUT); + + /* clear in and out data toggle */ + USB_CLEAR_TXDTS(ept_info->eptn); + USB_CLEAR_RXDTS(ept_info->eptn); + + /* toggle tx data toggle flag */ + USB_TOGGLE_TXDTS(ept_info->eptn); + + /* set endpoint reception status: valid */ + USB_SET_RXSTS(ept_info->eptn, USB_RX_VALID); + + /* set endpoint transmision status: disable */ + USB_SET_TXSTS(ept_info->eptn, USB_TX_DISABLE); + } + } + UNUSED(usbx); +} + + +/** + * @brief close usb endpoint + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @param ept_info: endpoint information structure + * @retval none + */ +void usb_ept_close(usbd_type *usbx, usb_ept_info *ept_info) +{ + if(ept_info->is_double_buffer == 0) + { + if(ept_info->inout == DATA_TRANS_IN) + { + /*clear tx data toggle */ + USB_CLEAR_TXDTS(ept_info->eptn); + + /* set tx status: disable */ + USB_SET_TXSTS(ept_info->eptn, USB_TX_DISABLE); + } + else + { + /*clear rx data toggle */ + USB_CLEAR_RXDTS(ept_info->eptn); + + /* set rx status: disable */ + USB_SET_RXSTS(ept_info->eptn, USB_RX_DISABLE); + + } + } + else + { + /* double buffer */ + + /*clear rx and tx data toggle */ + USB_CLEAR_TXDTS(ept_info->eptn); + USB_CLEAR_RXDTS(ept_info->eptn); + + if(ept_info->inout == DATA_TRANS_IN) + { + /* toggle tx */ + USB_TOGGLE_TXDTS(ept_info->eptn); + + /* set tx and rx status: disable */ + USB_SET_TXSTS(ept_info->eptn, USB_TX_DISABLE); + USB_SET_RXSTS(ept_info->eptn, USB_RX_DISABLE); + } + else + { + /* toggle rx */ + USB_TOGGLE_RXDTS(ept_info->eptn); + + /* set tx and rx status: disable */ + USB_SET_TXSTS(ept_info->eptn, USB_TX_DISABLE); + USB_SET_RXSTS(ept_info->eptn, USB_RX_DISABLE); + } + } + UNUSED(usbx); +} + +/** + * @brief write data from user memory to usb buffer + * @param pusr_buf: point to user buffer + * @param offset_addr: endpoint tx offset address + * @param nbytes: number of bytes data write to usb buffer + * @retval none + */ +void usb_write_packet(uint8_t *pusr_buf, uint16_t offset_addr, uint16_t nbytes) +{ + /* endpoint tx buffer address */ + __IO uint16_t *d_addr = (__IO uint16_t *)(offset_addr * 2 + g_usb_packet_address); + + uint32_t nhbytes = (nbytes + 1) >> 1; + uint32_t n_index; + uint16_t *pbuf = (uint16_t *)pusr_buf; + for(n_index = 0; n_index < nhbytes; n_index ++) + { +#if defined (__ICCARM__) && (__VER__ < 7000000) + *d_addr++ = *(__packed uint16_t *)pbuf; +#else + *d_addr++ = __UNALIGNED_UINT16_READ(pbuf); +#endif + d_addr ++; + pbuf ++; + } +} + +/** + * @brief read data from usb buffer to user buffer + * @param pusr_buf: point to user buffer + * @param offset_addr: endpoint rx offset address + * @param nbytes: number of bytes data write to usb buffer + * @retval none + */ +void usb_read_packet(uint8_t *pusr_buf, uint16_t offset_addr, uint16_t nbytes) +{ + __IO uint16_t *s_addr = (__IO uint16_t *)(offset_addr * 2 + g_usb_packet_address); + uint32_t nhbytes = (nbytes + 1) >> 1; + uint32_t n_index; + uint16_t *pbuf = (uint16_t *)pusr_buf; + for(n_index = 0; n_index < nhbytes; n_index ++) + { +#if defined (__ICCARM__) && (__VER__ < 7000000) + *(__packed uint16_t *)pbuf = *(__IO uint16_t *)s_addr ++; +#else + __UNALIGNED_UINT16_WRITE(pbuf, *(__IO uint16_t *)s_addr ++); +#endif + s_addr ++; + pbuf ++; + } +} + + +/** + * @brief usb interrupt enable + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @param interrupt: + * this parameter can be any combination of the following values: + * - USB_LSOF_INT + * - USB_SOF_INT + * - USB_RST_INT + * - USB_SP_INT + * - USB_WK_INT + * - USB_BE_INT + * - USB_UCFOR_INT + * - USB_TC_INT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void usb_interrupt_enable(usbd_type *usbx, uint16_t interrupt, confirm_state new_state) +{ + if(new_state == TRUE) + { + usbx->ctrl |= interrupt; + } + else + { + usbx->ctrl &= ~interrupt; + } +} + +/** + * @brief set the host assignment address + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @param address: host assignment address + * @retval none + */ +void usb_set_address(usbd_type *usbx, uint8_t address) +{ + usbx->devaddr_bit.addr = address; + usbx->devaddr_bit.cen = TRUE; +} + +/** + * @brief set endpoint tx or rx status to stall + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @param ept_info: endpoint information structure + * @retval none + */ +void usb_ept_stall(usbd_type *usbx, usb_ept_info *ept_info) +{ + if(ept_info->inout == DATA_TRANS_IN) + { + USB_SET_TXSTS(ept_info->eptn, USB_TX_STALL) + } + else + { + USB_SET_RXSTS(ept_info->eptn, USB_RX_STALL) + } + UNUSED(usbx); +} + +/** + * @brief usb device enter suspend mode + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @retval none + */ +void usb_enter_suspend(usbd_type *usbx) +{ + usbx->ctrl_bit.ssp = TRUE; + usbx->ctrl_bit.lpm = TRUE; +} + +/** + * @brief usb device exit suspend mode + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @retval none + */ +void usb_exit_suspend(usbd_type *usbx) +{ + usbx->ctrl_bit.ssp = FALSE; + usbx->ctrl_bit.lpm = FALSE; +} + +/** + * @brief usb remote wakeup set + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @retval none + */ +void usb_remote_wkup_set(usbd_type *usbx) +{ + usbx->ctrl_bit.gresume = TRUE; +} + +/** + * @brief usb remote wakeup clear + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @retval none + */ +void usb_remote_wkup_clear(usbd_type *usbx) +{ + usbx->ctrl_bit.gresume = FALSE; +} + +/** + * @brief usb auto malloc endpoint buffer + * @param mapacket: endpoint support max packet size + * @retval none + */ +uint16_t usb_buffer_malloc(uint16_t maxpacket) +{ + uint16_t offset = g_usb_offset_addr; + g_usb_offset_addr += maxpacket; + return offset; +} + +/** + * @brief free usb endpoint buffer + * @param none + * @retval none + */ +void usb_buffer_free(void) +{ + g_usb_offset_addr = USB_ENDP_DESC_TABLE_OFFSET; +} + +/** + * @brief get flag of usb. + * @param usbx: select the usb peripheral + * @param flag: select the usb flag + * this parameter can be one of the following values: + * - USB_INOUT_FLAG + * - USB_LSOF_FLAG + * - USB_SOF_FLAG + * - USB_RST_FLAG + * - USB_SP_FLAG + * - USB_WK_FLAG + * - USB_BE_FLAG + * - USB_UCFOR_FLAG + * - USB_TC_FLAG + * @retval none + */ +flag_status usb_flag_get(usbd_type *usbx, uint16_t flag) +{ + flag_status status = RESET; + + if((usbx->intsts & flag) == RESET) + { + status = RESET; + } + else + { + status = SET; + } + return status; +} + +/** + * @brief get interrupt flag of usb. + * @param usbx: select the usb peripheral + * @param flag: select the usb flag + * this parameter can be one of the following values: + * - USB_LSOF_FLAG + * - USB_SOF_FLAG + * - USB_RST_FLAG + * - USB_SP_FLAG + * - USB_WK_FLAG + * - USB_BE_FLAG + * - USB_UCFOR_FLAG + * - USB_TC_FLAG + * @retval none + */ +flag_status usb_interrupt_flag_get(usbd_type *usbx, uint16_t flag) +{ + flag_status status = RESET; + + if(flag == USB_TC_FLAG) + { + if(usbx->intsts & USB_TC_FLAG) + status = SET; + } + else + { + if((usbx->intsts & flag) && (usbx->ctrl & flag)) + { + status = SET; + } + } + return status; +} + +/** + * @brief clear flag of usb. + * @param usbx: select the usb peripheral + * @param flag: select the usb flag + * this parameter can be one of the following values: + * - USB_INOUT_FLAG + * - USB_LSOF_FLAG + * - USB_SOF_FLAG + * - USB_RST_FLAG + * - USB_SP_FLAG + * - USB_WK_FLAG + * - USB_BE_FLAG + * - USB_UCFOR_FLAG + * - USB_TC_FLAG + * @retval none + */ +void usb_flag_clear(usbd_type *usbx, uint16_t flag) +{ + usbx->intsts = ~flag; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f403a_407_wdt.c b/libraries/drivers/src/at32f403a_407_wdt.c new file mode 100644 index 0000000..b1c55d4 --- /dev/null +++ b/libraries/drivers/src/at32f403a_407_wdt.c @@ -0,0 +1,143 @@ +/** + ************************************************************************** + * @file at32f403a_407_wdt.c + * @brief contains all the functions for the wdt firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup WDT + * @brief WDT driver modules + * @{ + */ + +#ifdef WDT_MODULE_ENABLED + +/** @defgroup WDT_private_functions + * @{ + */ + +/** + * @brief wdt enable ,the reload value will be sent to the counter + * @param none + * @retval none + */ +void wdt_enable(void) +{ + WDT->cmd = WDT_CMD_ENABLE; +} + +/** + * @brief reload wdt counter + * @param none + * @retval none + */ +void wdt_counter_reload(void) +{ + WDT->cmd = WDT_CMD_RELOAD; +} + +/** + * @brief set wdt counter reload value + * @param reload_value (0x0000~0x0FFF) + * @retval none + */ +void wdt_reload_value_set(uint16_t reload_value) +{ + WDT->rld = reload_value; +} + +/** + * @brief set wdt division divider + * @param division + * this parameter can be one of the following values: + * - WDT_CLK_DIV_4 + * - WDT_CLK_DIV_8 + * - WDT_CLK_DIV_16 + * - WDT_CLK_DIV_32 + * - WDT_CLK_DIV_64 + * - WDT_CLK_DIV_128 + * - WDT_CLK_DIV_256 + * @retval none + */ +void wdt_divider_set(wdt_division_type division) +{ + WDT->div_bit.div = division; +} + +/** + * @brief enable or disable wdt cmd register write + * @param new_state (TRUE or FALSE) + * @retval none + */ +void wdt_register_write_enable( confirm_state new_state) +{ + if(new_state == FALSE) + { + WDT->cmd = WDT_CMD_LOCK; + } + else + { + WDT->cmd = WDT_CMD_UNLOCK; + } +} + +/** + * @brief get wdt flag + * @param wdt_flag + * this parameter can be one of the following values: + * - WDT_DIVF_UPDATE_FLAG: division value update complete flag. + * - WDT_RLDF_UPDATE_FLAG: reload value update complete flag. + * @retval state of wdt flag + */ +flag_status wdt_flag_get(uint16_t wdt_flag) +{ + flag_status status = RESET; + + if ((WDT->sts & wdt_flag) != (uint16_t)RESET) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f403a_407_wwdt.c b/libraries/drivers/src/at32f403a_407_wwdt.c new file mode 100644 index 0000000..03bb3ff --- /dev/null +++ b/libraries/drivers/src/at32f403a_407_wwdt.c @@ -0,0 +1,149 @@ +/** + ************************************************************************** + * @file at32f403a_407_wwdt.c + * @brief contains all the functions for the wwdt firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup WWDT + * @brief WWDT driver modules + * @{ + */ + +#ifdef WWDT_MODULE_ENABLED + +/** @defgroup WWDT_private_functions + * @{ + */ + +/** + * @brief wwdt reset by crm reset register + * @retval none + */ +void wwdt_reset(void) +{ + crm_periph_reset(CRM_WWDT_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_WWDT_PERIPH_RESET, FALSE); +} + +/** + * @brief wwdt division set + * @param division + * this parameter can be one of the following values: + * - WWDT_PCLK1_DIV_4096 (wwdt counter clock = (pclk1/4096)/1) + * - WWDT_PCLK1_DIV_8192 (wwdt counter clock = (pclk1/4096)/2) + * - WWDT_PCLK1_DIV_16384 (wwdt counter clock = (pclk1/4096)/4) + * - WWDT_PCLK1_DIV_32768 (wwdt counter clock = (pclk1/4096)/8) + * @retval none + */ +void wwdt_divider_set(wwdt_division_type division) +{ + WWDT->cfg_bit.div = division; +} + +/** + * @brief wwdt reload counter interrupt flag clear + * @param none + * @retval none + */ +void wwdt_flag_clear(void) +{ + WWDT->sts = 0; +} + +/** + * @brief wwdt enable and the counter value load + * @param wwdt_cnt (0x40~0x7f) + * @retval none + */ +void wwdt_enable(uint8_t wwdt_cnt) +{ + WWDT->ctrl = wwdt_cnt | WWDT_EN_BIT; +} + +/** + * @brief wwdt reload counter interrupt enable + * @param none + * @retval none + */ +void wwdt_interrupt_enable(void) +{ + WWDT->cfg_bit.rldien = TRUE; +} + +/** + * @brief wwdt reload counter interrupt flag get + * @param none + * @retval state of reload counter interrupt flag + */ +flag_status wwdt_flag_get(void) +{ + return (flag_status)WWDT->sts_bit.rldf; +} + +/** + * @brief wwdt reload counter interrupt flag get + * @param none + * @retval state of reload counter interrupt flag + */ +flag_status wwdt_interrupt_flag_get(void) +{ + return (flag_status)(WWDT->sts_bit.rldf && WWDT->cfg_bit.rldien); +} + +/** + * @brief wwdt counter value set + * @param wwdt_cnt (0x40~0x7f) + * @retval none + */ +void wwdt_counter_set(uint8_t wwdt_cnt) +{ + WWDT->ctrl_bit.cnt = wwdt_cnt; +} + +/** + * @brief wwdt window counter value set + * @param window_cnt (0x40~0x7f) + * @retval none + */ +void wwdt_window_counter_set(uint8_t window_cnt) +{ + WWDT->cfg_bit.win = window_cnt; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f403a_407_xmc.c b/libraries/drivers/src/at32f403a_407_xmc.c new file mode 100644 index 0000000..987c0de --- /dev/null +++ b/libraries/drivers/src/at32f403a_407_xmc.c @@ -0,0 +1,547 @@ +/** + ************************************************************************** + * @file at32f403a_407_xmc.c + * @brief contains all the functions for the xmc firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup XMC + * @brief XMC driver modules + * @{ + */ + +#ifdef XMC_MODULE_ENABLED + +/** @defgroup XMC_private_functions + * @{ + */ + +/** + * @brief xmc nor or sram registers reset + * @param xmc_subbank + * this parameter can be one of the following values: + * - XMC_BANK1_NOR_SRAM1 + * - XMC_BANK1_NOR_SRAM4 + * @retval none + */ +void xmc_nor_sram_reset(xmc_nor_sram_subbank_type xmc_subbank) +{ + /* XMC_BANK1_NORSRAM1 */ + if(xmc_subbank == XMC_BANK1_NOR_SRAM1) + { + XMC_BANK1->ctrl_tmg_group[xmc_subbank].bk1ctrl = 0x000030DB; + } + /* XMC_BANK1_NORSRAM2, XMC_BANK1_NORSRAM3 or XMC_BANK1_NORSRAM4 */ + else + { + XMC_BANK1->ctrl_tmg_group[xmc_subbank].bk1ctrl = 0x000030D2; + } + XMC_BANK1->ctrl_tmg_group[xmc_subbank].bk1tmg = 0x0FFFFFFF; + XMC_BANK1->tmgwr_group[xmc_subbank].bk1tmgwr = 0x0FFFFFFF; +} + +/** + * @brief initialize the xmc nor/sram banks according to the specified + * parameters in the xmc_norsraminitstruct. + * @param xmc_norsram_init_struct : pointer to a xmc_norsram_init_type + * structure that contains the configuration information for + * the xmc nor/sram specified banks. + * @retval none + */ +void xmc_nor_sram_init(xmc_norsram_init_type* xmc_norsram_init_struct) +{ + /* bank1 nor/sram control register configuration */ + XMC_BANK1->ctrl_tmg_group[xmc_norsram_init_struct->subbank].bk1ctrl = + (uint32_t)xmc_norsram_init_struct->data_addr_multiplex | + xmc_norsram_init_struct->device | + xmc_norsram_init_struct->bus_type | + xmc_norsram_init_struct->burst_mode_enable | + xmc_norsram_init_struct->asynwait_enable | + xmc_norsram_init_struct->wait_signal_lv | + xmc_norsram_init_struct->wrapped_mode_enable | + xmc_norsram_init_struct->wait_signal_config | + xmc_norsram_init_struct->write_enable | + xmc_norsram_init_struct->wait_signal_enable | + xmc_norsram_init_struct->write_timing_enable | + xmc_norsram_init_struct->write_burst_syn; + + /* if nor flash device */ + if(xmc_norsram_init_struct->device == XMC_DEVICE_NOR) + { + XMC_BANK1->ctrl_tmg_group[xmc_norsram_init_struct->subbank].bk1ctrl_bit.noren = 0x1; + } +} + +/** + * @brief initialize the xmc nor/sram banks according to the specified + * parameters in the xmc_rw_timing_struct and xmc_w_timing_struct. + * @param xmc_rw_timing_struct : pointer to a xmc_norsram_timing_init_type + * structure that contains the configuration information for + * the xmc nor/sram specified banks. + * @param xmc_w_timing_struct : pointer to a xmc_norsram_timing_init_type + * structure that contains the configuration information for + * the xmc nor/sram specified banks. + * @retval none + */ +void xmc_nor_sram_timing_config(xmc_norsram_timing_init_type* xmc_rw_timing_struct, + xmc_norsram_timing_init_type* xmc_w_timing_struct) +{ + /* bank1 nor/sram timing register configuration */ + XMC_BANK1->ctrl_tmg_group[xmc_rw_timing_struct->subbank].bk1tmg = + (uint32_t)xmc_rw_timing_struct->addr_setup_time | + (xmc_rw_timing_struct->addr_hold_time << 4) | + (xmc_rw_timing_struct->data_setup_time << 8) | + (xmc_rw_timing_struct->bus_latency_time <<16) | + (xmc_rw_timing_struct->clk_psc << 20) | + (xmc_rw_timing_struct->data_latency_time << 24) | + xmc_rw_timing_struct->mode; + + /* bank1 nor/sram timing register for write configuration, if extended mode is used */ + if(xmc_rw_timing_struct->write_timing_enable == XMC_WRITE_TIMING_ENABLE) + { + XMC_BANK1->tmgwr_group[xmc_w_timing_struct->subbank].bk1tmgwr = + (uint32_t)xmc_w_timing_struct->addr_setup_time | + (xmc_w_timing_struct->addr_hold_time << 4) | + (xmc_w_timing_struct->data_setup_time << 8) | + (xmc_w_timing_struct->bus_latency_time << 16) | + (xmc_w_timing_struct->clk_psc << 20) | + (xmc_w_timing_struct->data_latency_time << 24) | + xmc_w_timing_struct->mode; + } + else + { + XMC_BANK1->tmgwr_group[xmc_w_timing_struct->subbank].bk1tmgwr = 0x0FFFFFFF; + } +} + +/** + * @brief fill each xmc_nor_sram_init_struct member with its default value. + * @param xmc_nor_sram_init_struct: pointer to a xmc_norsram_init_type + * structure which will be initialized. + * @retval none + */ +void xmc_norsram_default_para_init(xmc_norsram_init_type* xmc_nor_sram_init_struct) +{ + /* reset nor/sram init structure parameters values */ + xmc_nor_sram_init_struct->subbank = XMC_BANK1_NOR_SRAM1; + xmc_nor_sram_init_struct->data_addr_multiplex = XMC_DATA_ADDR_MUX_ENABLE; + xmc_nor_sram_init_struct->device = XMC_DEVICE_SRAM; + xmc_nor_sram_init_struct->bus_type = XMC_BUSTYPE_8_BITS; + xmc_nor_sram_init_struct->burst_mode_enable = XMC_BURST_MODE_DISABLE; + xmc_nor_sram_init_struct->asynwait_enable = XMC_ASYN_WAIT_DISABLE; + xmc_nor_sram_init_struct->wait_signal_lv = XMC_WAIT_SIGNAL_LEVEL_LOW; + xmc_nor_sram_init_struct->wrapped_mode_enable = XMC_WRAPPED_MODE_DISABLE; + xmc_nor_sram_init_struct->wait_signal_config = XMC_WAIT_SIGNAL_SYN_BEFORE; + xmc_nor_sram_init_struct->write_enable = XMC_WRITE_OPERATION_ENABLE; + xmc_nor_sram_init_struct->wait_signal_enable = XMC_WAIT_SIGNAL_ENABLE; + xmc_nor_sram_init_struct->write_timing_enable = XMC_WRITE_TIMING_DISABLE; + xmc_nor_sram_init_struct->write_burst_syn = XMC_WRITE_BURST_SYN_DISABLE; +} + +/** + * @brief fill each xmc_rw_timing_struct and xmc_w_timing_struct member with its default value. + * @param xmc_rw_timing_struct: pointer to a xmc_norsram_timing_init_type + * structure which will be initialized. + * @param xmc_w_timing_struct: pointer to a xmc_norsram_timing_init_type + * structure which will be initialized. + * @retval none + */ +void xmc_norsram_timing_default_para_init(xmc_norsram_timing_init_type* xmc_rw_timing_struct, + xmc_norsram_timing_init_type* xmc_w_timing_struct) +{ + xmc_rw_timing_struct->subbank = XMC_BANK1_NOR_SRAM1; + xmc_rw_timing_struct->write_timing_enable = XMC_WRITE_TIMING_DISABLE; + xmc_rw_timing_struct->addr_setup_time = 0xF; + xmc_rw_timing_struct->addr_hold_time = 0xF; + xmc_rw_timing_struct->data_setup_time = 0xFF; + xmc_rw_timing_struct->bus_latency_time = 0xF; + xmc_rw_timing_struct->clk_psc = 0xF; + xmc_rw_timing_struct->data_latency_time = 0xF; + xmc_rw_timing_struct->mode = XMC_ACCESS_MODE_A; + xmc_w_timing_struct->subbank = XMC_BANK1_NOR_SRAM1; + xmc_w_timing_struct->write_timing_enable = XMC_WRITE_TIMING_DISABLE; + xmc_w_timing_struct->addr_setup_time = 0xF; + xmc_w_timing_struct->addr_hold_time = 0xF; + xmc_w_timing_struct->data_setup_time = 0xFF; + xmc_w_timing_struct->bus_latency_time = 0xF; + xmc_w_timing_struct->clk_psc = 0xF; + xmc_w_timing_struct->data_latency_time = 0xF; + xmc_w_timing_struct->mode = XMC_ACCESS_MODE_A; +} + +/** + * @brief enable or disable the specified nor/sram memory bank. + * @param xmc_subbank + * this parameter can be one of the following values: + * - XMC_BANK1_NOR_SRAM1 + * - XMC_BANK1_NOR_SRAM4 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void xmc_nor_sram_enable(xmc_nor_sram_subbank_type xmc_subbank, confirm_state new_state) +{ + XMC_BANK1->ctrl_tmg_group[xmc_subbank].bk1ctrl_bit.en = new_state; +} + +/** + * @brief config the bus turnaround phase. + * @param xmc_sub_bank + * this parameter can be one of the following values: + * - XMC_BANK1_NOR_SRAM1 + * - XMC_BANK1_NOR_SRAM4 + * @param w2w_timing :write timing + * @param r2r_timing :read timing + * @retval none + */ +void xmc_ext_timing_config(volatile xmc_nor_sram_subbank_type xmc_sub_bank, uint16_t w2w_timing, uint16_t r2r_timing) +{ + XMC_BANK1->ext_bit[xmc_sub_bank].buslatr2r = r2r_timing; + XMC_BANK1->ext_bit[xmc_sub_bank].buslatw2w = w2w_timing; +} + +/** + * @brief xmc nand flash registers reset + * @param xmc_bank + * this parameter can be one of the following values: + * - XMC_BANK2_NAND + * @retval none + */ +void xmc_nand_reset(xmc_class_bank_type xmc_bank) +{ + /* set the XMC_BANK2_NAND registers to their reset values */ + if(xmc_bank == XMC_BANK2_NAND) + { + XMC_BANK2->bk2ctrl = 0x00000018; + XMC_BANK2->bk2is = 0x00000040; + XMC_BANK2->bk2tmgatt = 0xFCFCFCFC; + XMC_BANK2->bk2tmgmem = 0xFCFCFCFC; + } +} + +/** + * @brief initialize the xmc nand banks according to the specified + * parameters in the xmc_nandinitstruct. + * @param xmc_nand_init_struct : pointer to a xmc_nand_init_type + * structure that contains the configuration information for the xmc + * nand specified banks. + * @retval none + */ +void xmc_nand_init(xmc_nand_init_type* xmc_nand_init_struct) +{ + uint32_t tempctrl = 0x0; + + /* Set the tempctrl value according to xmc_nand_init_struct parameters */ + tempctrl = (uint32_t)xmc_nand_init_struct->wait_enable | + xmc_nand_init_struct->bus_type | + xmc_nand_init_struct->ecc_enable | + xmc_nand_init_struct->ecc_pagesize | + (xmc_nand_init_struct->delay_time_cycle << 9) | + (xmc_nand_init_struct->delay_time_ar << 13) | + 0x00000008; + + /* xmc_bank2_nand registers configuration */ + if(xmc_nand_init_struct->nand_bank == XMC_BANK2_NAND) + { + XMC_BANK2->bk2ctrl = tempctrl; + } +} + +/** + * @brief initialize the xmc nand banks according to the specified + * parameters in the xmc_nandinitstruct. + * @param xmc_regular_spacetiming_struct : pointer to a xmc_nand_timinginit_type + * structure that contains the configuration information for the xmc + * nand specified banks. + * @param xmc_special_spacetiming_struct : pointer to a xmc_nand_timinginit_type + * structure that contains the configuration information for the xmc + * nand specified banks. + * @retval none + */ +void xmc_nand_timing_config(xmc_nand_timinginit_type* xmc_regular_spacetiming_struct, + xmc_nand_timinginit_type* xmc_special_spacetiming_struct) +{ + uint32_t tempmem = 0x0, tempatt = 0x0; + + /* set the tempmem value according to xmc_nand_init_struct parameters */ + tempmem = (uint32_t)xmc_regular_spacetiming_struct->mem_setup_time | + (xmc_regular_spacetiming_struct->mem_waite_time << 8) | + (xmc_regular_spacetiming_struct->mem_hold_time << 16) | + (xmc_regular_spacetiming_struct->mem_hiz_time << 24); + + /* set the tempatt value according to xmc_nand_init_struct parameters */ + tempatt = (uint32_t)xmc_special_spacetiming_struct->mem_setup_time | + (xmc_special_spacetiming_struct->mem_waite_time << 8) | + (xmc_special_spacetiming_struct->mem_hold_time << 16) | + (xmc_special_spacetiming_struct->mem_hiz_time << 24); + /* xmc_bank2_nand registers configuration */ + if(xmc_regular_spacetiming_struct->class_bank == XMC_BANK2_NAND) + { + XMC_BANK2->bk2tmgatt = tempatt; + XMC_BANK2->bk2tmgmem = tempmem; + } +} + +/** + * @brief fill each xmc_nand_init_struct member with its default value. + * @param xmc_nand_init_struct: pointer to a xmc_nand_init_type + * structure which will be initialized. + * @retval none + */ +void xmc_nand_default_para_init(xmc_nand_init_type* xmc_nand_init_struct) +{ + /* reset nand init structure parameters values */ + xmc_nand_init_struct->nand_bank = XMC_BANK2_NAND; + xmc_nand_init_struct->wait_enable = XMC_WAIT_OPERATION_DISABLE; + xmc_nand_init_struct->bus_type = XMC_BUSTYPE_8_BITS; + xmc_nand_init_struct->ecc_enable = XMC_ECC_OPERATION_DISABLE; + xmc_nand_init_struct->ecc_pagesize = XMC_ECC_PAGESIZE_256_BYTES; + xmc_nand_init_struct->delay_time_cycle = 0x0; + xmc_nand_init_struct->delay_time_ar = 0x0; +} + +/** + * @brief fill each xmc_common_spacetiming_struct and xmc_attribute_spacetiming_struct member with its default value. + * @param xmc_common_spacetiming_struct: pointer to a xmc_nand_timinginit_type + * structure which will be initialized. + * @param xmc_special_spacetiming_struct: pointer to a xmc_nand_timinginit_type + * structure which will be initialized. + * @retval none + */ +void xmc_nand_timing_default_para_init(xmc_nand_timinginit_type* xmc_regular_spacetiming_struct, + xmc_nand_timinginit_type* xmc_special_spacetiming_struct) +{ + xmc_regular_spacetiming_struct->class_bank = XMC_BANK2_NAND; + xmc_regular_spacetiming_struct->mem_hold_time = 0xFC; + xmc_regular_spacetiming_struct->mem_waite_time = 0xFC; + xmc_regular_spacetiming_struct->mem_setup_time = 0xFC; + xmc_regular_spacetiming_struct->mem_hiz_time = 0xFC; + xmc_special_spacetiming_struct->class_bank = XMC_BANK2_NAND; + xmc_special_spacetiming_struct->mem_hold_time = 0xFC; + xmc_special_spacetiming_struct->mem_waite_time = 0xFC; + xmc_special_spacetiming_struct->mem_setup_time = 0xFC; + xmc_special_spacetiming_struct->mem_hiz_time = 0xFC; +} + +/** + * @brief enable or disable the specified nand memory bank. + * @param xmc_bank: specifies the xmc bank to be used + * this parameter can be one of the following values: + * - XMC_BANK2_NAND + * @param new_state (TRUE or FALSE) + * @retval none + */ +void xmc_nand_enable(xmc_class_bank_type xmc_bank, confirm_state new_state) +{ + /* enable or disable the nand bank2 by setting the en bit in the bk2ctrl register */ + if(xmc_bank == XMC_BANK2_NAND) + { + XMC_BANK2->bk2ctrl_bit.en = new_state; + } +} + +/** + * @brief enable or disable the xmc nand ecc feature. + * @param xmc_bank: specifies the xmc bank to be used + * this parameter can be one of the following values: + * - XMC_BANK2_NAND + * @param new_state (TRUE or FALSE) + * @retval none + */ +void xmc_nand_ecc_enable(xmc_class_bank_type xmc_bank, confirm_state new_state) +{ + /* enable the selected nand bank2 ecc function by setting the eccen bit in the bk2ctrl register */ + if(xmc_bank == XMC_BANK2_NAND) + { + XMC_BANK2->bk2ctrl_bit.eccen = new_state; + } +} + +/** + * @brief return the error correction code register value. + * @param xmc_bank: specifies the xmc bank to be used + * this parameter can be one of the following values: + * - XMC_BANK2_NAND + * @retval the error correction code (ecc) value. + */ +uint32_t xmc_ecc_get(xmc_class_bank_type xmc_bank) +{ + uint32_t eccvaule = 0x0; + + /* get the bk2ecc register value */ + if(xmc_bank == XMC_BANK2_NAND) + { + eccvaule = XMC_BANK2->bk2ecc; + } + + /* return the error correction code value */ + return eccvaule; +} + +/** + * @brief enable or disable the specified xmc interrupts. + * @param xmc_bank: specifies the xmc bank to be used + * this parameter can be one of the following values: + * - XMC_BANK2_NAND + * @param xmc_int: specifies the xmc interrupt sources to be enabled or disabled. + * this parameter can be any combination of the following values: + * - XMC_INT_RISING_EDGE + * - XMC_INT_LEVEL + * - XMC_INT_FALLING_EDGE + * @param new_state (TRUE or FALSE) + * @retval none + */ +void xmc_interrupt_enable(xmc_class_bank_type xmc_bank, xmc_interrupt_sources_type xmc_int, confirm_state new_state) +{ + if(new_state != FALSE) + { + /* enable the selected xmc_bank2 interrupts */ + if(xmc_bank == XMC_BANK2_NAND) + { + XMC_BANK2->bk2is |= xmc_int; + } + } + else + { + /* disable the selected xmc_bank2 interrupts */ + if(xmc_bank == XMC_BANK2_NAND) + { + XMC_BANK2->bk2is &= ~xmc_int; + } + } +} + +/** + * @brief check whether the specified xmc flag is set or not. + * @param xmc_bank: specifies the xmc bank to be used + * this parameter can be one of the following values: + * - XMC_BANK2_NAND + * @param xmc_flag: specifies the flag to check. + * this parameter can be any combination of the following values: + * - XMC_RISINGEDGE_FLAG + * - XMC_LEVEL_FLAG + * - XMC_FALLINGEDGE_FLAG + * - XMC_FEMPT_FLAG + * @retval none + */ +flag_status xmc_flag_status_get(xmc_class_bank_type xmc_bank, xmc_interrupt_flag_type xmc_flag) +{ + flag_status status = RESET; + uint32_t temp = 0; + + if(xmc_bank == XMC_BANK2_NAND) + { + temp = XMC_BANK2->bk2is; + } + /* get the flag status */ + if((temp & xmc_flag) == RESET) + { + status = RESET; + } + else + { + status = SET; + } + /* return the flag status */ + return status; +} + +/** + * @brief check whether the specified xmc interrupt flag is set or not. + * @param xmc_bank: specifies the xmc bank to be used + * this parameter can be one of the following values: + * - XMC_BANK2_NAND + * @param xmc_flag: specifies the flag to check. + * this parameter can be any combination of the following values: + * - XMC_RISINGEDGE_FLAG + * - XMC_LEVEL_FLAG + * - XMC_FALLINGEDGE_FLAG + * @retval none + */ +flag_status xmc_interrupt_flag_status_get(xmc_class_bank_type xmc_bank, xmc_interrupt_flag_type xmc_flag) +{ + flag_status status = RESET; + + switch(xmc_flag) + { + case XMC_RISINGEDGE_FLAG: + if(XMC_BANK2->bk2is_bit.reien && XMC_BANK2->bk2is_bit.res) + status = SET; + break; + + case XMC_LEVEL_FLAG: + if(XMC_BANK2->bk2is_bit.feien && XMC_BANK2->bk2is_bit.fes) + status = SET; + break; + + case XMC_FALLINGEDGE_FLAG: + if(XMC_BANK2->bk2is_bit.hlien && XMC_BANK2->bk2is_bit.hls) + status = SET; + break; + + default: + break; + } + + /* return the flag status */ + return status; +} + +/** + * @brief clear the xmc's pending flags. + * @param xmc_bank: specifies the xmc bank to be used + * this parameter can be one of the following values: + * - XMC_BANK2_NAND + * @param xmc_flag: specifies the flag to check. + * this parameter can be any combination of the following values: + * - XMC_RISINGEDGE_FLAG + * - XMC_LEVEL_FLAG + * - XMC_FALLINGEDGE_FLAG + * - XMC_FEMPT_FLAG + * @retval none + */ +void xmc_flag_clear(xmc_class_bank_type xmc_bank, xmc_interrupt_flag_type xmc_flag) +{ + __IO uint32_t int_state; + if(xmc_bank == XMC_BANK2_NAND) + { + int_state = XMC_BANK2->bk2is & 0x38; /* keep interrupt state */ + XMC_BANK2->bk2is = (~(xmc_flag | 0x38) | int_state); + } +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/project/MDK_V5/BC1C.uvoptx b/project/MDK_V5/BC1C.uvoptx index ea8db09..ae428f2 100644 --- a/project/MDK_V5/BC1C.uvoptx +++ b/project/MDK_V5/BC1C.uvoptx @@ -1,5 +1,5 @@ - + 1.0
### uVision Project, (C) Keil Software
diff --git a/project/MDK_V5/BC1C.uvprojx b/project/MDK_V5/BC1C.uvprojx index c06e51d..350d66a 100644 --- a/project/MDK_V5/BC1C.uvprojx +++ b/project/MDK_V5/BC1C.uvprojx @@ -1,5 +1,5 @@ - + 2.1
### uVision Project, (C) Keil Software
@@ -14,12 +14,12 @@ -AT32F403ARCT7 ArteryTek ArteryTek.AT32F403A_407_DFP.2.1.5 - IRAM(0x20000000,0x18000) IROM(0x08000000,0x40000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + IRAM(0x20000000,0x6000000) IROM(0x08000000,0x10000000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0AT32F403A_256 -FS08000000 -FL0400000 -FP0($$Device:-AT32F403ARCT7$Flash\AT32F403A_256.FLM)) 0 - $$Device:-AT32F403AVGT7$Device\Include\at32f403a_407.h + $$Device:-AT32F403ARCT7$Device\Include\at32f403a_407.h @@ -459,6 +459,11 @@ 1 ..\..\libraries\drivers\src\at32f403a_407_usart.c + + at32f403a_407_crc.c + 1 + ..\..\libraries\drivers\src\at32f403a_407_crc.c + diff --git a/project/inc/at32f403a_407_conf.h b/project/inc/at32f403a_407_conf.h index d6ef237..a9bbcdb 100644 --- a/project/inc/at32f403a_407_conf.h +++ b/project/inc/at32f403a_407_conf.h @@ -52,10 +52,10 @@ extern "C" { /* module define -------------------------------------------------------------*/ /*#define ACC_MODULE_ENABLED----------------------*/ -#define ADC_MODULE_ENABLED +/*#define ADC_MODULE_ENABLED----------------------*/ /*#define BPR_MODULE_ENABLED----------------------*/ #define CAN_MODULE_ENABLED -/*#define CRC_MODULE_ENABLED----------------------*/ +#define CRC_MODULE_ENABLED #define CRM_MODULE_ENABLED /*#define DAC_MODULE_ENABLED----------------------*/ #define DEBUG_MODULE_ENABLED diff --git a/project/inc/at32f403a_407_wk_config.h b/project/inc/at32f403a_407_wk_config.h index f0dd260..b112ff5 100644 --- a/project/inc/at32f403a_407_wk_config.h +++ b/project/inc/at32f403a_407_wk_config.h @@ -71,9 +71,6 @@ extern "C" { /* init gpio function. */ void wk_gpio_config(void); - /* init adc1 function. */ - void wk_adc1_init(void); - /* init i2c1 function. */ void wk_i2c1_init(void); @@ -107,6 +104,9 @@ extern "C" { /* init tmr12 function. */ void wk_tmr12_init(void); + /* init crc function. */ + void wk_crc_init(void); + /* add user code begin exported functions */ /* add user code end exported functions */ diff --git a/project/inc/by_crc16.h b/project/inc/by_crc16.h new file mode 100644 index 0000000..775ce41 --- /dev/null +++ b/project/inc/by_crc16.h @@ -0,0 +1,8 @@ +#ifndef _BY_CRC16_H_ +#define _BY_CRC16_H_ + +#include "at32f403a_407.h" + +uint16_t by_crc16_calculate(void *pbuffer, uint32_t length); + +#endif \ No newline at end of file diff --git a/project/inc/by_debug.h b/project/inc/by_debug.h index e8a9648..bbcb5ee 100644 --- a/project/inc/by_debug.h +++ b/project/inc/by_debug.h @@ -6,6 +6,25 @@ #define BY_DEBUG_USART_INDEX (USART1) +#define BY_DEBUG_LOG_MODE (2) // 0-not log, 1-no debug log, 2-all + +#if (BY_DEBUG_LOG_MODE == 2) +#define LOGI(format, ...) lwprintf("[INFO] " format "\r\n", ##__VA_ARGS__) +#define LOGW(format, ...) lwprintf("[WARN] " format "\r\n", ##__VA_ARGS__) +#define LOGE(format, ...) lwprintf("[ERR] " format "\r\n", ##__VA_ARGS__) +#define LOGD(format, ...) lwprintf("[DEBUG] " format "\r\n", ##__VA_ARGS__) +#elif (BY_DEBUG_LOG_MODE == 1) +#define LOGI(format, ...) lwprintf("[INFO] " format "\r\n", ##__VA_ARGS__) +#define LOGW(format, ...) lwprintf("[WARN] " format "\r\n", ##__VA_ARGS__) +#define LOGE(format, ...) lwprintf("[ERR] " format "\r\n", ##__VA_ARGS__) +#define LOGD(format, ...) +#elif (BY_DEBUG_LOG_MODE == 0) +#define LOGI(format, ...) +#define LOGW(format, ...) +#define LOGE(format, ...) +#define LOGD(format, ...) +#endif + void by_debug_init(void); #endif diff --git a/project/src/at32f403a_407_int.c b/project/src/at32f403a_407_int.c index 6410626..3942136 100644 --- a/project/src/at32f403a_407_int.c +++ b/project/src/at32f403a_407_int.c @@ -68,10 +68,10 @@ /* add user code end external variables */ /** - * @brief this function handles nmi exception. - * @param none - * @retval none - */ + * @brief this function handles nmi exception. + * @param none + * @retval none + */ void NMI_Handler(void) { /* add user code begin NonMaskableInt_IRQ 0 */ @@ -84,17 +84,18 @@ void NMI_Handler(void) } /** - * @brief this function handles hard fault exception. - * @param none - * @retval none - */ + * @brief this function handles hard fault exception. + * @param none + * @retval none + */ void HardFault_Handler(void) { /* add user code begin HardFault_IRQ 0 */ /* add user code end HardFault_IRQ 0 */ /* go to infinite loop when hard fault exception occurs */ - while (1) { + while (1) + { /* add user code begin W1_HardFault_IRQ 0 */ /* add user code end W1_HardFault_IRQ 0 */ @@ -102,17 +103,18 @@ void HardFault_Handler(void) } /** - * @brief this function handles memory manage exception. - * @param none - * @retval none - */ + * @brief this function handles memory manage exception. + * @param none + * @retval none + */ void MemManage_Handler(void) { /* add user code begin MemoryManagement_IRQ 0 */ /* add user code end MemoryManagement_IRQ 0 */ /* go to infinite loop when memory manage exception occurs */ - while (1) { + while (1) + { /* add user code begin W1_MemoryManagement_IRQ 0 */ /* add user code end W1_MemoryManagement_IRQ 0 */ @@ -120,17 +122,18 @@ void MemManage_Handler(void) } /** - * @brief this function handles bus fault exception. - * @param none - * @retval none - */ + * @brief this function handles bus fault exception. + * @param none + * @retval none + */ void BusFault_Handler(void) { /* add user code begin BusFault_IRQ 0 */ /* add user code end BusFault_IRQ 0 */ /* go to infinite loop when bus fault exception occurs */ - while (1) { + while (1) + { /* add user code begin W1_BusFault_IRQ 0 */ /* add user code end W1_BusFault_IRQ 0 */ @@ -138,17 +141,18 @@ void BusFault_Handler(void) } /** - * @brief this function handles usage fault exception. - * @param none - * @retval none - */ + * @brief this function handles usage fault exception. + * @param none + * @retval none + */ void UsageFault_Handler(void) { /* add user code begin UsageFault_IRQ 0 */ /* add user code end UsageFault_IRQ 0 */ /* go to infinite loop when usage fault exception occurs */ - while (1) { + while (1) + { /* add user code begin W1_UsageFault_IRQ 0 */ /* add user code end W1_UsageFault_IRQ 0 */ @@ -156,10 +160,10 @@ void UsageFault_Handler(void) } /** - * @brief this function handles svcall exception. - * @param none - * @retval none - */ + * @brief this function handles svcall exception. + * @param none + * @retval none + */ void SVC_Handler(void) { /* add user code begin SVCall_IRQ 0 */ @@ -171,10 +175,10 @@ void SVC_Handler(void) } /** - * @brief this function handles debug monitor exception. - * @param none - * @retval none - */ + * @brief this function handles debug monitor exception. + * @param none + * @retval none + */ void DebugMon_Handler(void) { /* add user code begin DebugMonitor_IRQ 0 */ @@ -186,10 +190,10 @@ void DebugMon_Handler(void) } /** - * @brief this function handles pendsv_handler exception. - * @param none - * @retval none - */ + * @brief this function handles pendsv_handler exception. + * @param none + * @retval none + */ void PendSV_Handler(void) { /* add user code begin PendSV_IRQ 0 */ @@ -201,10 +205,10 @@ void PendSV_Handler(void) } /** - * @brief this function handles USB Low Priority or CAN1 RX0 handler. - * @param none - * @retval none - */ + * @brief this function handles USB Low Priority or CAN1 RX0 handler. + * @param none + * @retval none + */ void USBFS_L_CAN1_RX0_IRQHandler(void) { /* add user code begin USBFS_L_CAN1_RX0_IRQ 0 */ @@ -221,14 +225,17 @@ void USBFS_L_CAN1_RX0_IRQHandler(void) } /** - * @brief this function handles USART1 handler. - * @param none - * @retval none - */ + * @brief this function handles USART1 handler. + * @param none + * @retval none + */ void USART1_IRQHandler(void) { /* add user code begin USART1_IRQ 0 */ - + if (SET == usart_flag_get(USART1, USART_RDBF_FLAG)) { + // usart_data_receive(USART1); + usart_flag_clear(USART1, USART_RDBF_FLAG); + } /* add user code end USART1_IRQ 0 */ /* add user code begin USART1_IRQ 1 */ @@ -236,10 +243,10 @@ void USART1_IRQHandler(void) } /** - * @brief this function handles USART2 handler. - * @param none - * @retval none - */ + * @brief this function handles USART2 handler. + * @param none + * @retval none + */ void USART2_IRQHandler(void) { /* add user code begin USART2_IRQ 0 */ @@ -254,10 +261,10 @@ void USART2_IRQHandler(void) } /** - * @brief this function handles USART3 handler. - * @param none - * @retval none - */ + * @brief this function handles USART3 handler. + * @param none + * @retval none + */ void USART3_IRQHandler(void) { /* add user code begin USART3_IRQ 0 */ @@ -272,10 +279,10 @@ void USART3_IRQHandler(void) } /** - * @brief this function handles TMR6 handler. - * @param none - * @retval none - */ + * @brief this function handles TMR6 handler. + * @param none + * @retval none + */ void TMR6_GLOBAL_IRQHandler(void) { /* add user code begin TMR6_GLOBAL_IRQ 0 */ @@ -289,10 +296,10 @@ void TMR6_GLOBAL_IRQHandler(void) } /** - * @brief this function handles CAN2 RX0 handler. - * @param none - * @retval none - */ + * @brief this function handles CAN2 RX0 handler. + * @param none + * @retval none + */ void CAN2_RX0_IRQHandler(void) { /* add user code begin CAN2_RX0_IRQ 0 */ diff --git a/project/src/at32f403a_407_wk_config.c b/project/src/at32f403a_407_wk_config.c index fd6d947..e829d53 100644 --- a/project/src/at32f403a_407_wk_config.c +++ b/project/src/at32f403a_407_wk_config.c @@ -62,23 +62,23 @@ /* add user code end 0 */ /** - * @brief system clock config program - * @note the system clock is configured as follow: - * system clock (sclk) = hick / 12 * pll_mult - * system clock source = HICK_VALUE - * - hext = HEXT_VALUE - * - sclk = 240000000 - * - ahbdiv = 1 - * - ahbclk = 240000000 - * - apb1div = 2 - * - apb1clk = 120000000 - * - apb2div = 2 - * - apb2clk = 120000000 - * - pll_mult = 60 - * - pll_range = GT72MHZ (greater than 72 mhz) - * @param none - * @retval none - */ + * @brief system clock config program + * @note the system clock is configured as follow: + * system clock (sclk) = hick / 12 * pll_mult + * system clock source = HICK_VALUE + * - hext = HEXT_VALUE + * - sclk = 240000000 + * - ahbdiv = 1 + * - ahbclk = 240000000 + * - apb1div = 2 + * - apb1clk = 120000000 + * - apb2div = 2 + * - apb2clk = 120000000 + * - pll_mult = 60 + * - pll_range = GT72MHZ (greater than 72 mhz) + * @param none + * @retval none + */ void wk_system_clock_config(void) { /* reset crm */ @@ -88,21 +88,24 @@ void wk_system_clock_config(void) crm_clock_source_enable(CRM_CLOCK_SOURCE_LICK, TRUE); /* wait till lick is ready */ - while (crm_flag_get(CRM_LICK_STABLE_FLAG) != SET) { + while(crm_flag_get(CRM_LICK_STABLE_FLAG) != SET) + { } /* enable hext */ crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE); /* wait till hext is ready */ - while (crm_hext_stable_wait() == ERROR) { + while(crm_hext_stable_wait() == ERROR) + { } /* enable hick */ crm_clock_source_enable(CRM_CLOCK_SOURCE_HICK, TRUE); /* wait till hick is ready */ - while (crm_flag_get(CRM_HICK_STABLE_FLAG) != SET) { + while(crm_flag_get(CRM_HICK_STABLE_FLAG) != SET) + { } /* config pll clock resource */ @@ -112,7 +115,8 @@ void wk_system_clock_config(void) crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE); /* wait till pll is ready */ - while (crm_flag_get(CRM_PLL_STABLE_FLAG) != SET) { + while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET) + { } /* config ahbclk */ @@ -131,7 +135,8 @@ void wk_system_clock_config(void) crm_sysclk_switch(CRM_SCLK_PLL); /* wait till pll is used as system clock source */ - while (crm_sysclk_switch_status_get() != CRM_SCLK_PLL) { + while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL) + { } /* disable auto step mode */ @@ -142,12 +147,15 @@ void wk_system_clock_config(void) } /** - * @brief config periph clock - * @param none - * @retval none - */ + * @brief config periph clock + * @param none + * @retval none + */ void wk_periph_clock_config(void) { + /* enable crc periph clock */ + crm_periph_clock_enable(CRM_CRC_PERIPH_CLOCK, TRUE); + /* enable iomux periph clock */ crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE); @@ -163,9 +171,6 @@ void wk_periph_clock_config(void) /* enable gpiod periph clock */ crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE); - /* enable adc1 periph clock */ - crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE); - /* enable tmr8 periph clock */ crm_periph_clock_enable(CRM_TMR8_PERIPH_CLOCK, TRUE); @@ -201,10 +206,10 @@ void wk_periph_clock_config(void) } /** - * @brief init debug function. - * @param none - * @retval none - */ + * @brief init debug function. + * @param none + * @retval none + */ void wk_debug_config(void) { /* jtag-dp disabled and sw-dp enabled */ @@ -212,10 +217,10 @@ void wk_debug_config(void) } /** - * @brief nvic config - * @param none - * @retval none - */ + * @brief nvic config + * @param none + * @retval none + */ void wk_nvic_config(void) { nvic_priority_group_config(NVIC_PRIORITY_GROUP_4); @@ -229,10 +234,10 @@ void wk_nvic_config(void) } /** - * @brief init gpio_input/gpio_output/gpio_analog/eventout function. - * @param none - * @retval none - */ + * @brief init gpio_input/gpio_output/gpio_analog/eventout function. + * @param none + * @retval none + */ void wk_gpio_config(void) { /* add user code begin gpio_config 0 */ @@ -266,10 +271,10 @@ void wk_gpio_config(void) gpio_bits_reset(GPIOC, GPIO_PINS_0 | GPIO_PINS_1 | GPIO_PINS_2 | GPIO_PINS_3); gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT; - gpio_init_struct.gpio_pins = GPIO_PINS_0 | GPIO_PINS_1 | GPIO_PINS_2 | GPIO_PINS_3; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT; + gpio_init_struct.gpio_pins = GPIO_PINS_0 | GPIO_PINS_1 | GPIO_PINS_2 | GPIO_PINS_3; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(GPIOC, &gpio_init_struct); /* add user code begin gpio_config 2 */ @@ -278,10 +283,10 @@ void wk_gpio_config(void) } /** - * @brief init i2c1 function. - * @param none - * @retval none - */ + * @brief init i2c1 function. + * @param none + * @retval none + */ void wk_i2c1_init(void) { /* add user code begin i2c1_init 0 */ @@ -297,19 +302,19 @@ void wk_i2c1_init(void) /* add user code end i2c1_init 1 */ /* configure the SCL pin */ - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; - gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; - gpio_init_struct.gpio_pins = GPIO_PINS_6; + gpio_init_struct.gpio_pins = GPIO_PINS_6; gpio_init(GPIOB, &gpio_init_struct); /* configure the SDA pin */ - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; - gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; - gpio_init_struct.gpio_pins = GPIO_PINS_7; + gpio_init_struct.gpio_pins = GPIO_PINS_7; gpio_init(GPIOB, &gpio_init_struct); i2c_init(I2C1, I2C_FSMODE_DUTY_2_1, 100000); @@ -326,10 +331,10 @@ void wk_i2c1_init(void) } /** - * @brief init i2c2 function. - * @param none - * @retval none - */ + * @brief init i2c2 function. + * @param none + * @retval none + */ void wk_i2c2_init(void) { /* add user code begin i2c2_init 0 */ @@ -343,21 +348,21 @@ void wk_i2c2_init(void) /* add user code begin i2c2_init 1 */ /* add user code end i2c2_init 1 */ - + /* configure the SCL pin */ - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; - gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; - gpio_init_struct.gpio_pins = GPIO_PINS_10; + gpio_init_struct.gpio_pins = GPIO_PINS_10; gpio_init(GPIOB, &gpio_init_struct); /* configure the SDA pin */ - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; - gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; - gpio_init_struct.gpio_pins = GPIO_PINS_11; + gpio_init_struct.gpio_pins = GPIO_PINS_11; gpio_init(GPIOB, &gpio_init_struct); i2c_init(I2C2, I2C_FSMODE_DUTY_2_1, 100000); @@ -374,10 +379,10 @@ void wk_i2c2_init(void) } /** - * @brief init usart1 function - * @param none - * @retval none - */ + * @brief init usart1 function + * @param none + * @retval none + */ void wk_usart1_init(void) { /* add user code begin usart1_init 0 */ @@ -393,18 +398,18 @@ void wk_usart1_init(void) /* configure the TX pin */ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_mode = GPIO_MODE_MUX; - gpio_init_struct.gpio_pins = GPIO_PINS_9; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_pins = GPIO_PINS_9; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(GPIOA, &gpio_init_struct); /* configure the RX pin */ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; - gpio_init_struct.gpio_pins = GPIO_PINS_10; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; + gpio_init_struct.gpio_pins = GPIO_PINS_10; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(GPIOA, &gpio_init_struct); /* configure param */ @@ -431,10 +436,10 @@ void wk_usart1_init(void) } /** - * @brief init usart2 function - * @param none - * @retval none - */ + * @brief init usart2 function + * @param none + * @retval none + */ void wk_usart2_init(void) { /* add user code begin usart2_init 0 */ @@ -450,18 +455,18 @@ void wk_usart2_init(void) /* configure the TX pin */ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_mode = GPIO_MODE_MUX; - gpio_init_struct.gpio_pins = GPIO_PINS_2; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_pins = GPIO_PINS_2; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(GPIOA, &gpio_init_struct); /* configure the RX pin */ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; - gpio_init_struct.gpio_pins = GPIO_PINS_3; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; + gpio_init_struct.gpio_pins = GPIO_PINS_3; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(GPIOA, &gpio_init_struct); /* configure param */ @@ -488,10 +493,10 @@ void wk_usart2_init(void) } /** - * @brief init usart3 function - * @param none - * @retval none - */ + * @brief init usart3 function + * @param none + * @retval none + */ void wk_usart3_init(void) { /* add user code begin usart3_init 0 */ @@ -507,18 +512,18 @@ void wk_usart3_init(void) /* configure the TX pin */ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_mode = GPIO_MODE_MUX; - gpio_init_struct.gpio_pins = GPIO_PINS_10; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_pins = GPIO_PINS_10; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(GPIOC, &gpio_init_struct); /* configure the RX pin */ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; - gpio_init_struct.gpio_pins = GPIO_PINS_11; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; + gpio_init_struct.gpio_pins = GPIO_PINS_11; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(GPIOC, &gpio_init_struct); gpio_pin_remap_config(USART3_GMUX_0001, TRUE); @@ -547,10 +552,10 @@ void wk_usart3_init(void) } /** - * @brief init tmr6 function. - * @param none - * @retval none - */ + * @brief init tmr6 function. + * @param none + * @retval none + */ void wk_tmr6_init(void) { /* add user code begin tmr6_init 0 */ @@ -585,10 +590,10 @@ void wk_tmr6_init(void) } /** - * @brief init tmr8 function. - * @param none - * @retval none - */ + * @brief init tmr8 function. + * @param none + * @retval none + */ void wk_tmr8_init(void) { /* add user code begin tmr8_init 0 */ @@ -606,34 +611,34 @@ void wk_tmr8_init(void) /* add user code end tmr8_init 1 */ /* configure the CH1 pin */ - gpio_init_struct.gpio_pins = GPIO_PINS_6; - gpio_init_struct.gpio_mode = GPIO_MODE_MUX; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_pins = GPIO_PINS_6; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; gpio_init(GPIOC, &gpio_init_struct); /* configure the CH2 pin */ - gpio_init_struct.gpio_pins = GPIO_PINS_7; - gpio_init_struct.gpio_mode = GPIO_MODE_MUX; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_pins = GPIO_PINS_7; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; gpio_init(GPIOC, &gpio_init_struct); /* configure the CH3 pin */ - gpio_init_struct.gpio_pins = GPIO_PINS_8; - gpio_init_struct.gpio_mode = GPIO_MODE_MUX; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_pins = GPIO_PINS_8; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; gpio_init(GPIOC, &gpio_init_struct); /* configure the CH4 pin */ - gpio_init_struct.gpio_pins = GPIO_PINS_9; - gpio_init_struct.gpio_mode = GPIO_MODE_MUX; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_pins = GPIO_PINS_9; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; gpio_init(GPIOC, &gpio_init_struct); @@ -649,63 +654,64 @@ void wk_tmr8_init(void) tmr_primary_mode_select(TMR8, TMR_PRIMARY_SEL_RESET); /* configure channel 1 output settings */ - tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_OFF; - tmr_output_struct.oc_output_state = TRUE; + tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_OFF; + tmr_output_struct.oc_output_state = TRUE; tmr_output_struct.occ_output_state = FALSE; - tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; - tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; - tmr_output_struct.oc_idle_state = FALSE; - tmr_output_struct.occ_idle_state = FALSE; + tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.oc_idle_state = FALSE; + tmr_output_struct.occ_idle_state = FALSE; tmr_output_channel_config(TMR8, TMR_SELECT_CHANNEL_1, &tmr_output_struct); tmr_channel_value_set(TMR8, TMR_SELECT_CHANNEL_1, 0); tmr_output_channel_buffer_enable(TMR8, TMR_SELECT_CHANNEL_1, FALSE); /* configure channel 2 output settings */ - tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_OFF; - tmr_output_struct.oc_output_state = TRUE; + tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_OFF; + tmr_output_struct.oc_output_state = TRUE; tmr_output_struct.occ_output_state = FALSE; - tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; - tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; - tmr_output_struct.oc_idle_state = FALSE; - tmr_output_struct.occ_idle_state = FALSE; + tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.oc_idle_state = FALSE; + tmr_output_struct.occ_idle_state = FALSE; tmr_output_channel_config(TMR8, TMR_SELECT_CHANNEL_2, &tmr_output_struct); tmr_channel_value_set(TMR8, TMR_SELECT_CHANNEL_2, 0); tmr_output_channel_buffer_enable(TMR8, TMR_SELECT_CHANNEL_2, FALSE); /* configure channel 3 output settings */ - tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_OFF; - tmr_output_struct.oc_output_state = TRUE; + tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_OFF; + tmr_output_struct.oc_output_state = TRUE; tmr_output_struct.occ_output_state = FALSE; - tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; - tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; - tmr_output_struct.oc_idle_state = FALSE; - tmr_output_struct.occ_idle_state = FALSE; + tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.oc_idle_state = FALSE; + tmr_output_struct.occ_idle_state = FALSE; tmr_output_channel_config(TMR8, TMR_SELECT_CHANNEL_3, &tmr_output_struct); tmr_channel_value_set(TMR8, TMR_SELECT_CHANNEL_3, 0); tmr_output_channel_buffer_enable(TMR8, TMR_SELECT_CHANNEL_3, FALSE); /* configure channel 4 output settings */ - tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_OFF; - tmr_output_struct.oc_output_state = TRUE; + tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_OFF; + tmr_output_struct.oc_output_state = TRUE; tmr_output_struct.occ_output_state = FALSE; - tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; - tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; - tmr_output_struct.oc_idle_state = FALSE; - tmr_output_struct.occ_idle_state = FALSE; + tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.oc_idle_state = FALSE; + tmr_output_struct.occ_idle_state = FALSE; tmr_output_channel_config(TMR8, TMR_SELECT_CHANNEL_4, &tmr_output_struct); tmr_channel_value_set(TMR8, TMR_SELECT_CHANNEL_4, 0); tmr_output_channel_buffer_enable(TMR8, TMR_SELECT_CHANNEL_4, FALSE); /* configure break and dead-time settings */ - tmr_brkdt_struct.brk_enable = FALSE; + tmr_brkdt_struct.brk_enable = FALSE; tmr_brkdt_struct.auto_output_enable = FALSE; - tmr_brkdt_struct.brk_polarity = TMR_BRK_INPUT_ACTIVE_LOW; - tmr_brkdt_struct.fcsoen_state = FALSE; - tmr_brkdt_struct.fcsodis_state = FALSE; - tmr_brkdt_struct.wp_level = TMR_WP_OFF; - tmr_brkdt_struct.deadtime = 0; + tmr_brkdt_struct.brk_polarity = TMR_BRK_INPUT_ACTIVE_LOW; + tmr_brkdt_struct.fcsoen_state = FALSE; + tmr_brkdt_struct.fcsodis_state = FALSE; + tmr_brkdt_struct.wp_level = TMR_WP_OFF; + tmr_brkdt_struct.deadtime = 0; tmr_brkdt_config(TMR8, &tmr_brkdt_struct); + tmr_output_enable(TMR8, TRUE); tmr_counter_enable(TMR8, TRUE); @@ -716,10 +722,10 @@ void wk_tmr8_init(void) } /** - * @brief init tmr11 function. - * @param none - * @retval none - */ + * @brief init tmr11 function. + * @param none + * @retval none + */ void wk_tmr11_init(void) { /* add user code begin tmr11_init 0 */ @@ -735,10 +741,10 @@ void wk_tmr11_init(void) /* add user code end tmr11_init 1 */ /* configure the CH1 pin */ - gpio_init_struct.gpio_pins = GPIO_PINS_9; - gpio_init_struct.gpio_mode = GPIO_MODE_MUX; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_pins = GPIO_PINS_9; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; gpio_init(GPIOB, &gpio_init_struct); @@ -749,13 +755,13 @@ void wk_tmr11_init(void) tmr_period_buffer_enable(TMR11, FALSE); /* configure channel 1 output settings */ - tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A; - tmr_output_struct.oc_output_state = TRUE; + tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A; + tmr_output_struct.oc_output_state = TRUE; tmr_output_struct.occ_output_state = FALSE; - tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; - tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; - tmr_output_struct.oc_idle_state = FALSE; - tmr_output_struct.occ_idle_state = FALSE; + tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.oc_idle_state = FALSE; + tmr_output_struct.occ_idle_state = FALSE; tmr_output_channel_config(TMR11, TMR_SELECT_CHANNEL_1, &tmr_output_struct); tmr_channel_value_set(TMR11, TMR_SELECT_CHANNEL_1, 0); tmr_output_channel_buffer_enable(TMR11, TMR_SELECT_CHANNEL_1, FALSE); @@ -770,10 +776,10 @@ void wk_tmr11_init(void) } /** - * @brief init tmr12 function. - * @param none - * @retval none - */ + * @brief init tmr12 function. + * @param none + * @retval none + */ void wk_tmr12_init(void) { /* add user code begin tmr12_init 0 */ @@ -789,18 +795,18 @@ void wk_tmr12_init(void) /* add user code end tmr12_init 1 */ /* configure the CH1 pin */ - gpio_init_struct.gpio_pins = GPIO_PINS_14; - gpio_init_struct.gpio_mode = GPIO_MODE_MUX; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_pins = GPIO_PINS_14; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; gpio_init(GPIOB, &gpio_init_struct); /* configure the CH2 pin */ - gpio_init_struct.gpio_pins = GPIO_PINS_15; - gpio_init_struct.gpio_mode = GPIO_MODE_MUX; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_pins = GPIO_PINS_15; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; gpio_init(GPIOB, &gpio_init_struct); @@ -811,25 +817,25 @@ void wk_tmr12_init(void) tmr_period_buffer_enable(TMR12, FALSE); /* configure channel 1 output settings */ - tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_OFF; - tmr_output_struct.oc_output_state = TRUE; + tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_OFF; + tmr_output_struct.oc_output_state = TRUE; tmr_output_struct.occ_output_state = FALSE; - tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; - tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; - tmr_output_struct.oc_idle_state = FALSE; - tmr_output_struct.occ_idle_state = FALSE; + tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.oc_idle_state = FALSE; + tmr_output_struct.occ_idle_state = FALSE; tmr_output_channel_config(TMR12, TMR_SELECT_CHANNEL_1, &tmr_output_struct); tmr_channel_value_set(TMR12, TMR_SELECT_CHANNEL_1, 0); tmr_output_channel_buffer_enable(TMR12, TMR_SELECT_CHANNEL_1, FALSE); /* configure channel 2 output settings */ - tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_OFF; - tmr_output_struct.oc_output_state = TRUE; + tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_OFF; + tmr_output_struct.oc_output_state = TRUE; tmr_output_struct.occ_output_state = FALSE; - tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; - tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; - tmr_output_struct.oc_idle_state = FALSE; - tmr_output_struct.occ_idle_state = FALSE; + tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.oc_idle_state = FALSE; + tmr_output_struct.occ_idle_state = FALSE; tmr_output_channel_config(TMR12, TMR_SELECT_CHANNEL_2, &tmr_output_struct); tmr_channel_value_set(TMR12, TMR_SELECT_CHANNEL_2, 0); tmr_output_channel_buffer_enable(TMR12, TMR_SELECT_CHANNEL_2, FALSE); @@ -842,16 +848,16 @@ void wk_tmr12_init(void) } /** - * @brief init can1 function. - * @param none - * @retval none - */ + * @brief init can1 function. + * @param none + * @retval none + */ void wk_can1_init(void) { /* add user code begin can1_init 0 */ /* add user code end can1_init 0 */ - + gpio_init_type gpio_init_struct; can_base_type can_base_struct; can_baudrate_type can_baudrate_struct; @@ -860,57 +866,57 @@ void wk_can1_init(void) /* add user code begin can1_init 1 */ /* add user code end can1_init 1 */ - - /*gpio-----------------------------------------------------------------------------*/ + + /*gpio-----------------------------------------------------------------------------*/ gpio_default_para_init(&gpio_init_struct); /* configure the CAN1 TX pin */ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_mode = GPIO_MODE_MUX; - gpio_init_struct.gpio_pins = GPIO_PINS_12; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_pins = GPIO_PINS_12; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(GPIOA, &gpio_init_struct); /* configure the CAN1 RX pin */ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; - gpio_init_struct.gpio_pins = GPIO_PINS_11; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; + gpio_init_struct.gpio_pins = GPIO_PINS_11; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(GPIOA, &gpio_init_struct); - /*can_base_init--------------------------------------------------------------------*/ + /*can_base_init--------------------------------------------------------------------*/ can_default_para_init(&can_base_struct); - can_base_struct.mode_selection = CAN_MODE_COMMUNICATE; - can_base_struct.ttc_enable = FALSE; - can_base_struct.aebo_enable = TRUE; - can_base_struct.aed_enable = TRUE; - can_base_struct.prsf_enable = FALSE; + can_base_struct.mode_selection = CAN_MODE_COMMUNICATE; + can_base_struct.ttc_enable = FALSE; + can_base_struct.aebo_enable = TRUE; + can_base_struct.aed_enable = TRUE; + can_base_struct.prsf_enable = FALSE; can_base_struct.mdrsel_selection = CAN_DISCARDING_FIRST_RECEIVED; - can_base_struct.mmssr_selection = CAN_SENDING_BY_ID; + can_base_struct.mmssr_selection = CAN_SENDING_BY_ID; can_base_init(CAN1, &can_base_struct); - /*can_baudrate_setting-------------------------------------------------------------*/ - /*set baudrate = pclk/(baudrate_div *(1 + bts1_size + bts2_size))------------------*/ - can_baudrate_struct.baudrate_div = 24; /*value: 1~0xFFF*/ - can_baudrate_struct.rsaw_size = CAN_RSAW_1TQ; /*value: 1~4*/ - can_baudrate_struct.bts1_size = CAN_BTS1_8TQ; /*value: 1~16*/ - can_baudrate_struct.bts2_size = CAN_BTS2_1TQ; /*value: 1~8*/ + /*can_baudrate_setting-------------------------------------------------------------*/ + /*set baudrate = pclk/(baudrate_div *(1 + bts1_size + bts2_size))------------------*/ + can_baudrate_struct.baudrate_div = 24; /*value: 1~0xFFF*/ + can_baudrate_struct.rsaw_size = CAN_RSAW_1TQ; /*value: 1~4*/ + can_baudrate_struct.bts1_size = CAN_BTS1_8TQ; /*value: 1~16*/ + can_baudrate_struct.bts2_size = CAN_BTS2_1TQ; /*value: 1~8*/ can_baudrate_set(CAN1, &can_baudrate_struct); /*can_filter_0_config--------------------------------------------------------------*/ can_filter_init_struct.filter_activate_enable = TRUE; - can_filter_init_struct.filter_number = 0; - can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0; - can_filter_init_struct.filter_bit = CAN_FILTER_16BIT; - can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK; + can_filter_init_struct.filter_number = 0; + can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0; + can_filter_init_struct.filter_bit = CAN_FILTER_16BIT; + can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK; /*Standard identifier + Mask Mode + Data/Remote frame: id/mask 11bit --------------*/ - can_filter_init_struct.filter_id_high = 0x0 << 5; - can_filter_init_struct.filter_id_low = 0x0 << 5; + can_filter_init_struct.filter_id_high = 0x0 << 5; + can_filter_init_struct.filter_id_low = 0x0 << 5; can_filter_init_struct.filter_mask_high = 0x0 << 5; - can_filter_init_struct.filter_mask_low = 0x0 << 5; + can_filter_init_struct.filter_mask_low = 0x0 << 5; can_filter_init(CAN1, &can_filter_init_struct); @@ -922,8 +928,8 @@ void wk_can1_init(void) * --void USBFS_L_CAN1_RX0_IRQHandler(void) */ - /*can1 rx0 interrupt config--------------------------------------------------------*/ - // can_interrupt_enable(CAN1, CAN_RF0MIEN_INT, TRUE); + /*can1 rx0 interrupt config--------------------------------------------------------*/ + //can_interrupt_enable(CAN1, CAN_RF0MIEN_INT, TRUE); /* add user code begin can1_init 2 */ can_interrupt_enable(CAN1, CAN_RF0MIEN_INT, TRUE); @@ -931,16 +937,16 @@ void wk_can1_init(void) } /** - * @brief init can2 function. - * @param none - * @retval none - */ + * @brief init can2 function. + * @param none + * @retval none + */ void wk_can2_init(void) { /* add user code begin can2_init 0 */ /* add user code end can2_init 0 */ - + gpio_init_type gpio_init_struct; can_base_type can_base_struct; can_baudrate_type can_baudrate_struct; @@ -949,57 +955,57 @@ void wk_can2_init(void) /* add user code begin can2_init 1 */ /* add user code end can2_init 1 */ - - /*gpio-----------------------------------------------------------------------------*/ + + /*gpio-----------------------------------------------------------------------------*/ gpio_default_para_init(&gpio_init_struct); /* configure the CAN2 TX pin */ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_mode = GPIO_MODE_MUX; - gpio_init_struct.gpio_pins = GPIO_PINS_13; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_pins = GPIO_PINS_13; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(GPIOB, &gpio_init_struct); /* configure the CAN2 RX pin */ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; - gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; - gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; - gpio_init_struct.gpio_pins = GPIO_PINS_12; - gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; + gpio_init_struct.gpio_pins = GPIO_PINS_12; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(GPIOB, &gpio_init_struct); - /*can_base_init--------------------------------------------------------------------*/ + /*can_base_init--------------------------------------------------------------------*/ can_default_para_init(&can_base_struct); - can_base_struct.mode_selection = CAN_MODE_COMMUNICATE; - can_base_struct.ttc_enable = FALSE; - can_base_struct.aebo_enable = TRUE; - can_base_struct.aed_enable = TRUE; - can_base_struct.prsf_enable = FALSE; + can_base_struct.mode_selection = CAN_MODE_COMMUNICATE; + can_base_struct.ttc_enable = FALSE; + can_base_struct.aebo_enable = TRUE; + can_base_struct.aed_enable = TRUE; + can_base_struct.prsf_enable = FALSE; can_base_struct.mdrsel_selection = CAN_DISCARDING_FIRST_RECEIVED; - can_base_struct.mmssr_selection = CAN_SENDING_BY_ID; + can_base_struct.mmssr_selection = CAN_SENDING_BY_ID; can_base_init(CAN2, &can_base_struct); - /*can_baudrate_setting-------------------------------------------------------------*/ - /*set baudrate = pclk/(baudrate_div *(1 + bts1_size + bts2_size))------------------*/ - can_baudrate_struct.baudrate_div = 24; /*value: 1~0xFFF*/ - can_baudrate_struct.rsaw_size = CAN_RSAW_1TQ; /*value: 1~4*/ - can_baudrate_struct.bts1_size = CAN_BTS1_8TQ; /*value: 1~16*/ - can_baudrate_struct.bts2_size = CAN_BTS2_1TQ; /*value: 1~8*/ + /*can_baudrate_setting-------------------------------------------------------------*/ + /*set baudrate = pclk/(baudrate_div *(1 + bts1_size + bts2_size))------------------*/ + can_baudrate_struct.baudrate_div = 24; /*value: 1~0xFFF*/ + can_baudrate_struct.rsaw_size = CAN_RSAW_1TQ; /*value: 1~4*/ + can_baudrate_struct.bts1_size = CAN_BTS1_8TQ; /*value: 1~16*/ + can_baudrate_struct.bts2_size = CAN_BTS2_1TQ; /*value: 1~8*/ can_baudrate_set(CAN2, &can_baudrate_struct); /*can_filter_0_config--------------------------------------------------------------*/ can_filter_init_struct.filter_activate_enable = TRUE; - can_filter_init_struct.filter_number = 0; - can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0; - can_filter_init_struct.filter_bit = CAN_FILTER_16BIT; - can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK; + can_filter_init_struct.filter_number = 0; + can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0; + can_filter_init_struct.filter_bit = CAN_FILTER_16BIT; + can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK; /*Standard identifier + Mask Mode + Data/Remote frame: id/mask 11bit --------------*/ - can_filter_init_struct.filter_id_high = 0x0 << 5; - can_filter_init_struct.filter_id_low = 0x0 << 5; + can_filter_init_struct.filter_id_high = 0x0 << 5; + can_filter_init_struct.filter_id_low = 0x0 << 5; can_filter_init_struct.filter_mask_high = 0x0 << 5; - can_filter_init_struct.filter_mask_low = 0x0 << 5; + can_filter_init_struct.filter_mask_low = 0x0 << 5; can_filter_init(CAN2, &can_filter_init_struct); @@ -1011,8 +1017,8 @@ void wk_can2_init(void) * --void CAN2_RX0_IRQHandler(void) */ - /*can2 rx0 interrupt config--------------------------------------------------------*/ - // can_interrupt_enable(CAN2, CAN_RF0MIEN_INT, TRUE); + /*can2 rx0 interrupt config--------------------------------------------------------*/ + //can_interrupt_enable(CAN2, CAN_RF0MIEN_INT, TRUE); /* add user code begin can2_init 2 */ can_interrupt_enable(CAN2, CAN_RF0MIEN_INT, TRUE); @@ -1020,64 +1026,26 @@ void wk_can2_init(void) } /** - * @brief init adc1 function. - * @param none - * @retval none - */ -void wk_adc1_init(void) + * @brief init crc function. + * @param none + * @retval none + */ +void wk_crc_init(void) { - /* add user code begin adc1_init 0 */ + /* add user code begin crc_init 0 */ - /* add user code end adc1_init 0 */ + /* add user code end crc_init 0 */ - gpio_init_type gpio_init_struct; - adc_base_config_type adc_base_struct; + crc_init_data_set(0xFFFFFFFF); + crc_poly_size_set(CRC_POLY_SIZE_16B); + crc_poly_value_set(0x8005); + crc_reverse_input_data_set(CRC_REVERSE_INPUT_BY_BYTE); + crc_reverse_output_data_set(CRC_REVERSE_OUTPUT_DATA); + crc_data_reset(); - gpio_default_para_init(&gpio_init_struct); + /* add user code begin crc_init 1 */ - /* add user code begin adc1_init 1 */ - - /* add user code end adc1_init 1 */ - - /*gpio--------------------------------------------------------------------*/ - /* configure the IN0 pin */ - gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG; - gpio_init_struct.gpio_pins = GPIO_PINS_0; - gpio_init(GPIOA, &gpio_init_struct); - - crm_adc_clock_div_set(CRM_ADC_DIV_6); - - /*adc_common_settings-------------------------------------------------------------*/ - adc_combine_mode_select(ADC_INDEPENDENT_MODE); - - /*adc_settings--------------------------------------------------------------------*/ - adc_base_default_para_init(&adc_base_struct); - adc_base_struct.sequence_mode = FALSE; - adc_base_struct.repeat_mode = FALSE; - adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT; - adc_base_struct.ordinary_channel_length = 1; - adc_base_config(ADC1, &adc_base_struct); - - /* adc_ordinary_conversionmode-------------------------------------------- */ - adc_ordinary_channel_set(ADC1, ADC_CHANNEL_0, 1, ADC_SAMPLETIME_1_5); - - adc_ordinary_conversion_trigger_set(ADC1, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE); - - adc_ordinary_part_mode_enable(ADC1, FALSE); - - adc_enable(ADC1, TRUE); - - /* adc calibration-------------------------------------------------------- */ - adc_calibration_init(ADC1); - while (adc_calibration_init_status_get(ADC1)) - ; - adc_calibration_start(ADC1); - while (adc_calibration_status_get(ADC1)) - ; - - /* add user code begin adc1_init 2 */ - - /* add user code end adc1_init 2 */ + /* add user code end crc_init 1 */ } /* add user code begin 1 */ diff --git a/project/src/by_crc16.c b/project/src/by_crc16.c new file mode 100644 index 0000000..61c69ea --- /dev/null +++ b/project/src/by_crc16.c @@ -0,0 +1,12 @@ +#include "by_crc16.h" + +uint16_t by_crc16_calculate(void *pbuffer, uint32_t length) +{ + const uint8_t *pbuffer_u8 = (uint8_t *)pbuffer; + + for (uint32_t index = 0; index < length; index++) { + (*(uint8_t *)&CRC->dt) = pbuffer_u8[index]; + } + + return (uint16_t)(CRC->dt & 0xFFFF); +} \ No newline at end of file diff --git a/project/src/main.c b/project/src/main.c index eb90cbb..8181e8f 100644 --- a/project/src/main.c +++ b/project/src/main.c @@ -32,6 +32,7 @@ #include "dwt_delay.h" #include "eeprom.h" #include "by_debug.h" +#include "by_crc16.h" /* add user code end private includes */ /* private typedef -----------------------------------------------------------*/ @@ -65,10 +66,10 @@ /* add user code end 0 */ /** - * @brief main function. - * @param none - * @retval none - */ + * @brief main function. + * @param none + * @retval none + */ int main(void) { /* add user code begin 1 */ @@ -102,9 +103,6 @@ int main(void) /* init i2c2 function. */ wk_i2c2_init(); - /* init adc1 function. */ - wk_adc1_init(); - /* init tmr6 function. */ wk_tmr6_init(); @@ -123,17 +121,28 @@ int main(void) /* init can2 function. */ wk_can2_init(); + /* init crc function. */ + wk_crc_init(); + /* init gpio function. */ wk_gpio_config(); /* add user code begin 2 */ - DWT_Init(); - flash_ee_init(); - lwprintf("init done!\r\n"); + /* dwt delay init */ + DWT_Init(); + LOGD("dwt init done"); + + /* simulative eeprom init */ + flash_ee_init(); + LOGD("eeprom init done"); + + LOGI("init done"); + /* add user code end 2 */ - while (1) { + while(1) + { /* add user code begin 3 */ // DWT_Delay(1000000); /* add user code end 3 */