/* ================================================================== >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<< ------------------------------------------------------------------ Copyright (c) 2019-2020 by Lattice Semiconductor Corporation ALL RIGHTS RESERVED ------------------------------------------------------------------ IMPORTANT: THIS FILE IS USED BY OR GENERATED BY the LATTICE PROPELâ„¢ DEVELOPMENT SUITE, WHICH INCLUDES PROPEL BUILDER AND PROPEL SDK. Lattice grants permission to use this code pursuant to the terms of the Lattice Propel License Agreement. DISCLAIMER: LATTICE MAKES NO WARRANTIES ON THIS FILE OR ITS CONTENTS, WHETHER EXPRESSED, IMPLIED, STATUTORY, OR IN ANY PROVISION OF THE LATTICE PROPEL LICENSE AGREEMENT OR COMMUNICATION WITH LICENSEE, AND LATTICE SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. LATTICE DOES NOT WARRANT THAT THE FUNCTIONS CONTAINED HEREIN WILL MEET LICENSEE 'S REQUIREMENTS, OR THAT LICENSEE' S OPERATION OF ANY DEVICE, SOFTWARE OR SYSTEM USING THIS FILE OR ITS CONTENTS WILL BE UNINTERRUPTED OR ERROR FREE, OR THAT DEFECTS HEREIN WILL BE CORRECTED. LICENSEE ASSUMES RESPONSIBILITY FOR SELECTION OF MATERIALS TO ACHIEVE ITS INTENDED RESULTS, AND FOR THE PROPER INSTALLATION, USE, AND RESULTS OBTAINED THEREFROM. LICENSEE ASSUMES THE ENTIRE RISK OF THE FILE AND ITS CONTENTS PROVING DEFECTIVE OR FAILING TO PERFORM PROPERLY AND IN SUCH EVENT, LICENSEE SHALL ASSUME THE ENTIRE COST AND RISK OF ANY REPAIR, SERVICE, CORRECTION, OR ANY OTHER LIABILITIES OR DAMAGES CAUSED BY OR ASSOCIATED WITH THE SOFTWARE.IN NO EVENT SHALL LATTICE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS FILE OR ITS CONTENTS, EVEN IF LATTICE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. LATTICE 'S SOLE LIABILITY, AND LICENSEE' S SOLE REMEDY, IS SET FORTH ABOVE. LATTICE DOES NOT WARRANT OR REPRESENT THAT THIS FILE, ITS CONTENTS OR USE THEREOF DOES NOT INFRINGE ON THIRD PARTIES' INTELLECTUAL PROPERTY RIGHTS, INCLUDING ANY PATENT. IT IS THE USER' S RESPONSIBILITY TO VERIFY THE USER SOFTWARE DESIGN FOR CONSISTENCY AND FUNCTIONALITY THROUGH THE USE OF FORMAL SOFTWARE VALIDATION METHODS. ------------------------------------------------------------------ ================================================================== */ #include #include "hal.h" /*************************************************************************/ /* initialize the gp timer ip * * this_timer : pointer to the gp_timer instance * base_address: base address of the gp_timer instance * clock: systerm clock * gp_timer_cnt num of timers(range: 1-8) * returns: 0 if configuration is successful, non-zero if configuration fails */ unsigned char gp_timer_init(struct gp_timer_instance *this_timer, unsigned int base_address, unsigned int clock, unsigned char gp_timer_cnt) { if(this_timer == NULL) return 1; if(gp_timer_cnt<1 || gp_timer_cnt >8) return 1; this_timer->base_addr = base_address; this_timer->timer_num = gp_timer_cnt; this_timer->sys_clk = clock; return 0; } /* * gp_timer_config: Configure the general-purpose timer * * this_timer: Pointer to the gp_timer_instance structure * timer_src: Timer source GP_TIMER0-GP_TIMER7(range: 0-7) * continuous: Whether to run continuously * pscaler: Prescaler value * dir: Counting direction * period: Period value * * returns: 0 if configuration is successful, non-zero if configuration fails */ unsigned char gp_timer_config(struct gp_timer_instance *this_timer, unsigned char timer_src, bool continuous,uint32_t pscaler,uint8_t dir,uint16_t period) { unsigned int cmp_val = 0; unsigned int wr_value=0; unsigned int snap=0; unsigned int status=0; if(this_timer == NULL) return 1; if(timer_src < GP_TIMER0 || timer_src >= this_timer->timer_num) return 1; this_timer->prescaler=(2<timer_clk[timer_src]=this_timer->sys_clk/this_timer->prescaler; this_timer->tc[timer_src].reload_value = this_timer->timer_clk[timer_src]/1000 * period; reg_32b_write(this_timer->base_addr | (TIMER0_PERIOD + timer_src *0x10), this_timer->tc[timer_src].reload_value); if(continuous) { this_timer->tc[timer_src].b_continue = continuous; wr_value=wr_value|0x01; } wr_value=wr_value | (pscaler<<8) | (dir<<1); reg_32b_write(this_timer->base_addr | TIMER0_CON | timer_src*0x10, 0x0000); reg_32b_modify(this_timer->base_addr | TIMER_INT_EN, 1<base_addr | GLB_CTRL, 1<base_addr | TIMER0_CON | timer_src*0x10, wr_value); reg_32b_modify(this_timer->base_addr | TIMER_INT, 1<= this_timer->timer_num) return 1; reg_32b_read(this_timer->base_addr | (timer_src * 0x10 | TIMER0_CNT),snapshot); return 0; } /* * gp_timer_start: Start the general-purpose timer * * this_timer: Pointer to the gp_timer_instance structure * timer_src: Timer source GP_TIMER0-GP_TIMER7 (range: 0-7) * timer_callback: Function to be called when the timer expires * context: Pointer to data to be passed to the timer_callback function * * returns: 0 if successful, non-zero if an error occurred */ unsigned char gp_timer_start(struct gp_timer_instance *this_timer, unsigned char timer_src, void (*timer_callback) (void *), void *context) { uint32_t status; if(this_timer == NULL || timer_callback == NULL) return 1; if(timer_src >= this_timer->timer_num || timer_src < GP_TIMER0) return 1; this_timer->callback_table[timer_src].timer_callback = timer_callback; this_timer->callback_table[timer_src].context = context; reg_32b_modify(this_timer->base_addr | TIMER0_CON | timer_src*0x10,TIMER_START ,0x04); //start timer return 0; } /* * gp_timer_stop: Stop the general-purpose timer * * this_timer: Pointer to the gp_timer_instance structure * timer_src: Timer source GP_TIMER0-GP_TIMER7 (range: 0-7) * * returns: 0 if successful, non-zero if an error occurred */ unsigned char gp_timer_stop(struct gp_timer_instance *this_timer, unsigned char timer_src) { if(this_timer == NULL || timer_src >= this_timer->timer_num || timer_src < GP_TIMER0) return 1; reg_32b_write(this_timer->base_addr | TIMER0_CON | timer_src*0x10, 0x08); return 0; } /* * gp_timer_isr: Interrupt service routine for timer */ void gp_timer_isr(void *ctx) { volatile struct gp_timer_instance *this_timer = (struct gp_timer_instance *) ctx; unsigned int int_status = 0; unsigned int snap=0; reg_32b_read(this_timer->base_addr | TIMER_INT,&int_status); reg_32b_write(this_timer->base_addr | TIMER_INT, int_status); for(int timer_src = GP_TIMER0; timer_src < this_timer->timer_num; timer_src++) { if(int_status & (1 << timer_src)) { if(this_timer->callback_table[timer_src].timer_callback) { this_timer->callback_table[timer_src].timer_callback(this_timer->callback_table[timer_src].context); } } } return; }