--- /dev/null
+\r
+/******************************************************************************\r
+*\r
+* alt_globaltmr.c - API for the Altera SoC FPGA global timer.\r
+*\r
+******************************************************************************/\r
+\r
+/******************************************************************************\r
+*\r
+* Copyright 2013 Altera Corporation. All Rights Reserved.\r
+*\r
+* Redistribution and use in source and binary forms, with or without\r
+* modification, are permitted provided that the following conditions are met:\r
+*\r
+* 1. Redistributions of source code must retain the above copyright notice,\r
+* this list of conditions and the following disclaimer.\r
+*\r
+* 2. Redistributions in binary form must reproduce the above copyright notice,\r
+* this list of conditions and the following disclaimer in the documentation\r
+* and/or other materials provided with the distribution.\r
+*\r
+* 3. The name of the author may not be used to endorse or promote products\r
+* derived from this software without specific prior written permission.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO\r
+* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+* OF SUCH DAMAGE.\r
+*\r
+******************************************************************************/\r
+\r
+\r
+\r
+#include <stdlib.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include "socal/hps.h"\r
+#include "socal/socal.h"\r
+#include "hwlib.h"\r
+#include "alt_mpu_registers.h"\r
+#include "alt_globaltmr.h"\r
+#include "alt_clock_manager.h" // for getting clock bus frequency\r
+\r
+\r
+\r
+/************************************************************************************************************/\r
+\r
+/************************************************************************************************************/\r
+/* The global timer is common to both ARM CPUs and also to the FPGA fabric.There is no good way to know what\r
+ effect halting the global timer might have on the other ARM CPU. It was decided that once the global\r
+ timer was started, there should not be a way included in this API to halt it. It is possible to achieve\r
+ much of the same effect by disabling the global timer comparison functionality instead. The global timer\r
+ has hardware that can automatically add the count value to the current value of the global timer when\r
+ the timer reaches the comparison value.\r
+*/\r
+/************************************************************************************************************/\r
+\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_is_running() is an internal function, not published in the API.\r
+ * It checks and returns the state of the enable bit of the global timer but doesn't check the comparison\r
+ * mode bit.\r
+*************************************************************************************************************/\r
+\r
+bool alt_globaltmr_is_running(void)\r
+{\r
+ return alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET) & GLOBALTMR_ENABLE_BIT;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* alt_globaltmr_uninit() uninitializes the global timer modules */\r
+/****************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_globaltmr_uninit(void)\r
+{\r
+ alt_clrbits_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET,\r
+ GLOBALTMR_COMP_ENABLE_BIT | GLOBALTMR_INT_ENABLE_BIT |\r
+ GLOBALTMR_AUTOINC_ENABLE_BIT);\r
+ // do NOT clear the global timer enable bit or prescaler setting\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_COMP_LO_REG_OFFSET, 0);\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_COMP_HI_REG_OFFSET, 0);\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_AUTOINC_REG_OFFSET, 0);\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_INT_STAT_REG_OFFSET, GLOBALTMR_INT_STATUS_BIT);\r
+ /* clear any interrupts by writing one to sticky bit */\r
+ return ALT_E_SUCCESS;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* alt_globaltmr_init() initializes the global timer module */\r
+/****************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_globaltmr_init(void)\r
+{\r
+ alt_globaltmr_uninit();\r
+ alt_setbits_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET, GLOBALTMR_ENABLE_BIT);\r
+ return ALT_E_SUCCESS;\r
+}\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_stop() doesn't actually stop the global timer, instead it stops the virtual representation\r
+ * of the global timer as a typical countdown timer. The timer will no longer compare the global timer value\r
+ * to the global timer compare value, will not auto-increment the comparator value, and will not set the\r
+ * interrupt.\r
+*************************************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_globaltmr_stop(void)\r
+{\r
+ uint32_t regdata; // value to read & write\r
+\r
+ regdata = alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET);\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET, regdata & ~GLOBALTMR_COMP_ENABLE_BIT);\r
+ return ALT_E_SUCCESS;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_start() sets the comparison mode of the global timer, allowing it to be used as a typical\r
+ * countdown timer. If auto-increment mode is enabled, it will operate as a free-running timer.\r
+*************************************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_globaltmr_start(void)\r
+{\r
+ uint32_t regdata; // value to read & write\r
+\r
+ regdata = alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET);\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET, regdata | (GLOBALTMR_COMP_ENABLE_BIT | GLOBALTMR_ENABLE_BIT));\r
+ return ALT_E_SUCCESS;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_get() returns the current value of the 64-bit global timer as two unsigned 32-bit quantities.\r
+*************************************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_globaltmr_get(uint32_t* highword, uint32_t* loword)\r
+{\r
+ ALT_STATUS_CODE ret = ALT_E_ERROR;\r
+ uint32_t hi, lo, temp; // temporary variables\r
+ uint32_t cnt = 3; // Timeout counter, do 3 tries\r
+\r
+ if ((highword == NULL) || (loword == NULL)) { ret = ALT_E_BAD_ARG; }\r
+ else\r
+ {\r
+ hi = alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CNTR_HI_REG_OFFSET);\r
+ do {\r
+ temp = hi;\r
+ lo = alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CNTR_LO_REG_OFFSET);\r
+ hi = alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CNTR_HI_REG_OFFSET);\r
+ } while ((temp != hi) && (cnt--)); // has the high-order word read the same twice yet?\r
+ // note that if the first condition is true, cnt is neither tested nor decremented\r
+\r
+ if (cnt) {\r
+ *highword = hi;\r
+ *loword = lo;\r
+ ret = ALT_E_SUCCESS;\r
+ }\r
+ }\r
+ return ret;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_get64() returns the current value of the global timer as an unsigned 64-bit quantity.\r
+*************************************************************************************************************/\r
+\r
+uint64_t alt_globaltmr_get64(void)\r
+{\r
+\r
+ uint64_t ret = 0; // zero a very unlikely value for this timer\r
+ uint32_t hi, lo, temp; // temporary variables\r
+ uint32_t cnt = 3; // Timeout counter, do 3 tries\r
+\r
+ hi = alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CNTR_HI_REG_OFFSET);\r
+ do {\r
+ temp = hi;\r
+ lo = alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CNTR_LO_REG_OFFSET);\r
+ hi = alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CNTR_HI_REG_OFFSET);\r
+ } while ((temp != hi) && (cnt--)); // has the high-order word read the same twice yet?\r
+ // note that if the first condition is true, cnt is neither tested nor decremented\r
+\r
+ if (cnt)\r
+ {\r
+ ret = (uint64_t) hi;\r
+ ret = (ret << (sizeof(uint32_t)*8)) | lo;\r
+ }\r
+ return ret;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_counter_get_low32() returns the least-significant 32 bits of the current global timer value.\r
+*************************************************************************************************************/\r
+\r
+uint32_t alt_globaltmr_counter_get_low32(void)\r
+{\r
+ return alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CNTR_LO_REG_OFFSET);\r
+\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_counter_get_hi32() returns the most-significant 32 bits of the current global timer value.\r
+*************************************************************************************************************/\r
+\r
+uint32_t alt_globaltmr_counter_get_hi32(void)\r
+{\r
+ return alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CNTR_HI_REG_OFFSET);\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_comp_set() writes the 64-bit comparator register with two 32-bit words.\r
+*************************************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_globaltmr_comp_set(uint32_t highword, uint32_t loword)\r
+{\r
+ bool was_comping = false;\r
+ ALT_STATUS_CODE ret = ALT_E_ERROR;\r
+\r
+ if (alt_globaltmr_is_comp_mode()) // necessary to prevent a spurious interrupt\r
+ {\r
+ was_comping = true;\r
+ ret = alt_globaltmr_comp_mode_stop();\r
+ if (ret != ALT_E_SUCCESS) { return ret; }\r
+ }\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_COMP_LO_REG_OFFSET, loword);\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_COMP_HI_REG_OFFSET, highword);\r
+ ret = ALT_E_SUCCESS;\r
+\r
+ if (was_comping) { ret = alt_globaltmr_comp_mode_start(); }\r
+ // If global timer was in comparison mode before, re-enable it before returning\r
+ return ret;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_comp_set64() writes the 64-bit comparator register with the supplied 64-bit value.\r
+*************************************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_globaltmr_comp_set64(uint64_t compval)\r
+{\r
+ ALT_STATUS_CODE ret = ALT_E_ERROR;\r
+ bool was_comping = false;\r
+\r
+ if (alt_globaltmr_is_comp_mode())\r
+ {\r
+ was_comping = true;\r
+ ret = alt_globaltmr_comp_mode_stop();\r
+ if (ret != ALT_E_SUCCESS) { return ret; }\r
+ }\r
+\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_COMP_LO_REG_OFFSET, (uint32_t) (compval & UINT32_MAX));\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_COMP_HI_REG_OFFSET,\r
+ (uint32_t) ((compval >> (sizeof(uint32_t)*8)) & UINT32_MAX));\r
+ ret = ALT_E_SUCCESS;\r
+\r
+ if (was_comping) { ret = alt_globaltmr_comp_mode_start(); }\r
+ // If global timer was in comparison mode before, re-enable it\r
+ return ret;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_comp_get() returns the 64 bits of the current global timer comparator value via two\r
+ * uint32_t pointers.\r
+*************************************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_globaltmr_comp_get(uint32_t *hiword, uint32_t *loword)\r
+{\r
+ if ((hiword == NULL) || (loword == NULL)) {return ALT_E_ERROR; }\r
+ *loword = alt_read_word(GLOBALTMR_BASE + GLOBALTMR_COMP_LO_REG_OFFSET);\r
+ *hiword = alt_read_word(GLOBALTMR_BASE + GLOBALTMR_COMP_HI_REG_OFFSET);\r
+ /* no need to read these multiple times since the register is not expected to change mid-read */\r
+ return ALT_E_SUCCESS;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_comp_get64() returns all 64 bits of the current global timer comparator value.\r
+*************************************************************************************************************/\r
+\r
+uint64_t alt_globaltmr_comp_get64(void)\r
+{\r
+ uint64_t ret;\r
+\r
+ ret = ((uint64_t) alt_read_word(GLOBALTMR_BASE + GLOBALTMR_COMP_HI_REG_OFFSET)) << (sizeof(uint32_t)*8);\r
+ ret = ret | ((uint64_t) alt_read_word(GLOBALTMR_BASE + GLOBALTMR_COMP_LO_REG_OFFSET));\r
+ return ret;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_remain_get64() returns a 64-bit quantity that represents the difference between the\r
+ * current comparator value and the current global timer value. If the comparator register was updated by\r
+ * the autoincrement circuitry (and the global timer has not subsequently crossed over the comparator\r
+ * value a second time), this difference will always be expressable in 32 bits. If the user has manually\r
+ * set the comparator value, however, this may not be true and more than 32 bits may be required to express\r
+ * the difference.\r
+*************************************************************************************************************/\r
+\r
+#define alt_globaltmr_remain_get64() (alt_globaltmr_comp_get64() - alt_globaltmr_get64())\r
+\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_remain_get() returns a 32-bit quantity that represents the difference between the\r
+ * current comparator value and the current global timer value. If the comparator register was updated by\r
+ * the autoincrement circuitry (and the global timer has not subsequently crossed over the comparator\r
+ * value a second time), this difference will always be expressable in 32 bits. If the user has manually\r
+ * set the comparator value, however, this may not be true and more than 32 bits may be required to express\r
+ * the difference.\r
+*************************************************************************************************************/\r
+\r
+uint32_t alt_globaltmr_remain_get(void)\r
+{\r
+ return (uint32_t) (alt_globaltmr_comp_get64() - alt_globaltmr_get64());\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_comp_mode_start() sets the comparison enable bit of the global timer, enabling\r
+ * comparison mode operation.\r
+*************************************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_globaltmr_comp_mode_start(void)\r
+{\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET,\r
+ alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET) | GLOBALTMR_COMP_ENABLE_BIT);\r
+ return ALT_E_SUCCESS;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_comp_mode_stop() clears the comparison enable bit of the global timer, disabling\r
+ * comparison mode operation.\r
+*************************************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_globaltmr_comp_mode_stop(void)\r
+{\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET,\r
+ alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET) & ~GLOBALTMR_COMP_ENABLE_BIT);\r
+ return ALT_E_SUCCESS;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_is_comp_mode() checks and returns the state of the comparison enable bit of the global timer.\r
+*************************************************************************************************************/\r
+\r
+bool alt_globaltmr_is_comp_mode(void)\r
+{\r
+ return alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET) & GLOBALTMR_COMP_ENABLE_BIT;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_prescaler_get() returns the value of the prescaler setting of the global timer, which is one\r
+ * less than the actual counter divisor. Valid output = 0-255.\r
+*************************************************************************************************************/\r
+\r
+uint32_t alt_globaltmr_prescaler_get(void)\r
+{\r
+ return (alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET) & GLOBALTMR_PS_MASK) >> GLOBALTMR_PS_SHIFT;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_prescaler_set() sets the prescaler value of the global timer, which is one\r
+ * less than the actual counter divisor.\r
+*************************************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_globaltmr_prescaler_set(uint32_t val)\r
+{\r
+ // It is not defined in the ARM global timer spec if the prescaler can be rewritten while\r
+ //the global timer is counting or not. This is how we find out:\r
+ uint32_t regdata;\r
+\r
+ if (val > UINT8_MAX) return ALT_E_BAD_ARG;\r
+ regdata = alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET) & ~GLOBALTMR_PS_MASK;\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET, regdata | (val << GLOBALTMR_PS_SHIFT));\r
+ return ALT_E_SUCCESS;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_autoinc_set() safely writes a value to the auto-increment register of the global timer.\r
+*************************************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_globaltmr_autoinc_set(uint32_t inc)\r
+{\r
+ ALT_STATUS_CODE ret = ALT_E_ERROR;\r
+ bool was_comping = false;\r
+\r
+ if (alt_globaltmr_is_comp_mode())\r
+ {\r
+ was_comping = true;\r
+ ret = alt_globaltmr_comp_mode_stop();\r
+ // if timer is currently in comparison mode, disable comparison mode\r
+ if (ret != ALT_E_SUCCESS) { return ret; }\r
+ }\r
+\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_AUTOINC_REG_OFFSET, inc);\r
+ ret = ALT_E_SUCCESS;\r
+\r
+ if (was_comping) { ret = alt_globaltmr_comp_mode_start(); }\r
+ // If global timer was in comparison mode before, re-enable it\r
+ return ret;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_autoinc_get() returns the value of the auto-increment register of the global timer.\r
+*************************************************************************************************************/\r
+\r
+uint32_t alt_globaltmr_autoinc_get(void)\r
+{\r
+ return alt_read_word(GLOBALTMR_BASE + GLOBALTMR_AUTOINC_REG_OFFSET);\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_autoinc_mode_start() sets the auto-increment enable bit of the global timer, putting it into\r
+ * auto-increment or periodic timer mode.\r
+*************************************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_globaltmr_autoinc_mode_start(void)\r
+{\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET,\r
+ alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET) | GLOBALTMR_AUTOINC_ENABLE_BIT);\r
+ return ALT_E_SUCCESS;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_autoinc_mode_stop() clears the auto-increment enable bit of the global timer, putting it into\r
+ * one-shot timer mode.\r
+*************************************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_globaltmr_autoinc_mode_stop(void)\r
+{\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET,\r
+ alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET) & ~GLOBALTMR_AUTOINC_ENABLE_BIT);\r
+ return ALT_E_SUCCESS;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_is_autoinc_mode() checks and returns the state of the auto-increment enable bit of the global\r
+ * timer.\r
+*************************************************************************************************************/\r
+\r
+bool alt_globaltmr_is_autoinc_mode(void)\r
+{\r
+ return alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET) & GLOBALTMR_AUTOINC_ENABLE_BIT;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_maxcounter_get() returns the maximum possible auto-increment value of the global timer.\r
+*************************************************************************************************************/\r
+\r
+uint32_t alt_globaltmr_maxcounter_get(void)\r
+{\r
+ return GLOBALTMR_MAX;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_int_disable() clears the interrupt enable bit of the global timer.\r
+*************************************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_globaltmr_int_disable(void)\r
+{\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET,\r
+ alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET) & ~GLOBALTMR_INT_ENABLE_BIT);\r
+ return ALT_E_SUCCESS;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_int_enable() sets the interrupt enable bit of the global timer, allowing the timer to throw an\r
+ * interrupt when the global timer value is greater than the comparator value. If the global timer has not\r
+ * yet been started, it tries to start it first.\r
+*************************************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_globaltmr_int_enable(void)\r
+{\r
+ if (!alt_globaltmr_is_running()) // Is gbl timer running?\r
+ {\r
+ if ( alt_globaltmr_start() != ALT_E_SUCCESS) { return ALT_E_ERROR; }\r
+ }\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET,\r
+ alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET) | GLOBALTMR_INT_ENABLE_BIT);\r
+ return ALT_E_SUCCESS;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_int_is_enabled() checks and returns the state of the interrupt bit of the global timer.\r
+*************************************************************************************************************/\r
+\r
+bool alt_globaltmr_int_is_enabled(void)\r
+{\r
+ return alt_read_word(GLOBALTMR_BASE + GLOBALTMR_CTRL_REG_OFFSET) & GLOBALTMR_INT_ENABLE_BIT;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_int_clear_pending() clears the status of the interrupt pending bit of the global timer.\r
+*************************************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_globaltmr_int_clear_pending(void)\r
+{\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_INT_STAT_REG_OFFSET, GLOBALTMR_INT_STATUS_BIT);\r
+ /* clear interrupt sticky bit by writing one to it */\r
+ return ALT_E_SUCCESS;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_int_is_pending() checks and returns the status of the interrupt pending bit of the global\r
+ * timer.\r
+*************************************************************************************************************/\r
+\r
+bool alt_globaltmr_int_is_pending(void)\r
+{\r
+ return alt_read_word(GLOBALTMR_BASE + GLOBALTMR_INT_STAT_REG_OFFSET) & GLOBALTMR_INT_STATUS_BIT;\r
+}\r
+\r
+\r
+/*************************************************************************************************************\r
+ * alt_globaltmr_int_if_pending_clear() checks and returns the status of the interrupt pending bit of the global\r
+ * timer. If the interrupt pending bit is set, this function also clears it.\r
+*************************************************************************************************************/\r
+\r
+bool alt_globaltmr_int_if_pending_clear(void)\r
+{\r
+ bool ret;\r
+\r
+ ret = alt_read_word(GLOBALTMR_BASE + GLOBALTMR_INT_STAT_REG_OFFSET) & GLOBALTMR_INT_STATUS_BIT;\r
+ if (ret)\r
+ {\r
+ alt_write_word(GLOBALTMR_BASE + GLOBALTMR_INT_STAT_REG_OFFSET, GLOBALTMR_INT_STATUS_BIT);\r
+ } //clear int by writing to sticky bit\r
+\r
+ return ret;\r
+}\r
+\r