/* ********************************************************************************************************* * 函 数 名: UartGetChar * 功能说明: 从串口接收缓冲区读取1字节数据 (用于主程序调用) * 形 参: _pUart : 串口设备 * _pByte : 存放读取数据的指针 * 返 回 值: 0 表示无数据 1表示读取到数据 ********************************************************************************************************* */ static uint8_t UartGetChar(UART_T *_pUart, uint8_t *_pByte) { uint16_t usCount; /* usRxWrite 变量在中断函数中被改写,主程序读取该变量时,必须进行临界区保护 */ DISABLE_INT(); usCount = _pUart->usRxCount; ENABLE_INT(); /* 如果读和写索引相同,则返回0 */ //if (_pUart->usRxRead == usRxWrite) if (usCount == 0) /* 已经没有数据 */ { return 0; } else { *_pByte = _pUart->pRxBuf[_pUart->usRxRead]; /* 从串口接收FIFO取1个数据 */ /* 改写FIFO读索引 */ DISABLE_INT(); if (++_pUart->usRxRead >= _pUart->usRxBufSize) { _pUart->usRxRead = 0; } _pUart->usRxCount--; ENABLE_INT(); return 1; } }
/* ********************************************************************************************************* * 函 数 名: bsp_DelayMS * 功能说明: ms级延迟,延迟精度为正负1ms * 形 参: n : 延迟长度,单位1 ms。 n 应大于2 * 返 回 值: 无 ********************************************************************************************************* */ void timerDelayMs ( uint32_t n ) { if ( n == 0 ) { return; } else if ( n == 1 ) { n = 2; } DISABLE_INT(); /* 关中断 */ s_uiDelayCount = n; s_ucTimeOutFlag = 0; ENABLE_INT(); /* 开中断 */ while ( 1 ) { // bsp_Idle(); /* CPU空闲执行的操作, 见 bsp.c 和 bsp.h 文件 */ /* 等待延迟时间到 注意:编译器认为 s_ucTimeOutFlag = 0,所以可能优化错误,因此 s_ucTimeOutFlag 变量必须申明为 volatile */ if ( s_ucTimeOutFlag == 1 ) { break; } } }
/* ********************************************************************************************************* * 函 数 名: Wwdg_Reload_Task * 功能说明: 窗口看门狗超喂狗任务。 * 形 参: * 返 回 值: 无 ********************************************************************************************************* */ void Wwdg_Reload_Task(void) { static uint32_t sys_time, time_ms = 0, time_add_up = 0; const uint32_t work_time_max = WWDG_RELOAD_GAP; uint32_t offset_time_ticks = 0; uint8_t timeout_flag = 0; DISABLE_INT(); /* 关中断 */ sys_time = Sys_Time; /* 这个变量在Systick中断中被改写,因此需要关中断进行保护 */ ENABLE_INT(); /* 开中断 */ if(WWDG_EN_MARK) { if(time_ms != sys_time) { if(time_ms < sys_time) { offset_time_ticks = sys_time - time_ms; time_ms = sys_time; if(((uint64_t)offset_time_ticks + (uint64_t)time_add_up) > UINT_LEAST32_MAX) { timeout_flag = 1; time_add_up = 0; } else if((offset_time_ticks + time_add_up) > work_time_max) { timeout_flag = 1; time_add_up = 0; } else { time_add_up += offset_time_ticks; } } else { offset_time_ticks = UINT_LEAST32_MAX + sys_time - time_ms; time_ms = sys_time; if(((uint64_t)offset_time_ticks + (uint64_t)time_add_up) > UINT_LEAST32_MAX) { timeout_flag = 1; time_add_up = 0; } else if((offset_time_ticks + time_add_up) > work_time_max) { timeout_flag = 1; time_add_up = 0; } else { time_add_up += offset_time_ticks; } } if(timeout_flag == 1) { timeout_flag = 0; Wwdg_Feed(); } } } }
static inline eCC3000States State() { ; intState save = DISABLE_INT(); eCC3000States rv = sSpiInformation.ulSpiState; ENABLE_INT(save); return rv; }
DMPAPI(void) io_DisableINT(void) { if (irq_cscnt == 0) { DISABLE_INT(); } // getting interrupts disabled, it is now safe to update irq_cscnt irq_cscnt++; }
/*---------------------------------------------------------------------------------------------- * 函数: StopTimeTick() * * 说明: 关闭时钟滴答(毫秒发生器) **--------------------------------------------------------------------------------------------*/ void apical StopTimeTick(void) { DISABLE_INT(); FamesSetVect(TickIntNo,DOS_TimeTick); outportb(0x43,0x36); outportb(0x40,0x00); outportb(0x40,0x00); ENABLE_INT(); }
static inline int Still(eCC3000States s) { int rv = 1; do { intState save = DISABLE_INT(); rv = (s == sSpiInformation.ulSpiState); ENABLE_INT(save); } while(rv && !sSpiInformation.abort); return !sSpiInformation.abort; }
/* ********************************************************************************************************* * 函 数 名: bsp_GetRunTime * 功能说明: 获取CPU运行时间,单位1ms。最长可以表示 24.85天,如果你的产品连续运行时间超过这个数,则必须考虑溢出问题 * 形 参: 无 * 返 回 值: CPU运行时间,单位1ms ********************************************************************************************************* */ uint32_t timerGetRun ( void ) { uint32_t runtime; DISABLE_INT(); /* 关中断 */ runtime = g_iRunTime; /* 这个变量在Systick中断中被改写,因此需要关中断进行保护 */ ENABLE_INT(); /* 开中断 */ return runtime; }
/* ********************************************************************************************************* * 函 数 名: UartSend * 功能说明: 填写数据到UART发送缓冲区,并启动发送中断。中断处理函数发送完毕后,自动关闭发送中断 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ static void UartSend(UART_T *_pUart, uint8_t *_ucaBuf, uint16_t _usLen) { uint16_t i; for (i = 0; i < _usLen; i++) { /* 如果发送缓冲区已经满了,则等待缓冲区空 */ while (1) { uint16_t usCount; DISABLE_INT(); usCount = _pUart->usTxCount; ENABLE_INT(); if (usCount < _pUart->usTxBufSize) { break; } } /* 将新数据填入发送缓冲区 */ _pUart->pTxBuf[_pUart->usTxWrite] = _ucaBuf[i]; DISABLE_INT(); if (++_pUart->usTxWrite >= _pUart->usTxBufSize) { _pUart->usTxWrite = 0; } _pUart->usTxCount++; ENABLE_INT(); } USART_ITConfig(_pUart->uart, USART_IT_TXE, ENABLE); }
static inline int Reserve(eCC3000States ns) { int idle = 0; do { intState save = DISABLE_INT(); idle = (eSPI_STATE_IDLE == sSpiInformation.ulSpiState); if (idle) { SetState(ns, eAssert); } ENABLE_INT(save); } while(!idle && !sSpiInformation.abort); return !sSpiInformation.abort; }
void spk_sched( void ) { spk_in_interrupt = 0; ENABLE_INT(); while( 1 ) { DISABLE_INT(); //if( spk_ready_list != NULL ) { if( spk_num_tasks != 0 ) { task_cb* task = spk_dequeue_task(); spk_dispatch(task); } else { SLEEP(); } } }
/*---------------------------------------------------------------------------------------------- * 函数: StartOS() * * 说明: 启动FamesOS并执行第一个任务 * * 备注: 应用程序不可调用 **--------------------------------------------------------------------------------------------*/ void apical StartOS(void) { CALLED_ONLY_ONCE(); outportbyte(0xA0,0x20); outportbyte(0x20,0x20); /* 发送一次EOI指令 */ ExitAppFlag=NO; setjmp(JumpBuf); if(ExitAppFlag){ return; } DISABLE_INT(); GetHighestTask(); FamesOSStarted=YES; FIRST_CONTEXT(); }
/*---------------------------------------------------------------------------------------------- * 函数: InitTimeTick() * * 说明: 安装时钟滴答(毫秒发生器) * * 备注: 将TimeTick挂到IRQ0之上, 并初始化8253定时器(Channel-0) **--------------------------------------------------------------------------------------------*/ void apical InitTimeTick(void) { INT16S hz,hzl,hzh; SecondsFromStart = 0L; hz=1193; hzl=hz%256; hzh=hz/256; DISABLE_INT(); DOS_TimeTick=FamesGetVect(TickIntNo); outportb(0x43,(INT08U)0x36); outportb(0x40,(INT08U)hzl); outportb(0x40,(INT08U)hzh); FamesSetVect(TickIntNo,TimeTick); ENABLE_INT(); }
/* ********************************************************************************************************* * 函 数 名: bsp_StopTimer * 功能说明: 停止一个定时器 * 形 参: _id : 定时器ID,值域【0,TMR_COUNT-1】。用户必须自行维护定时器ID,以避免定时器ID冲突。 * 返 回 值: 无 ********************************************************************************************************* */ void bsp_StopTimer(uint8_t _id) { if (_id >= TMR_COUNT) { /* 打印出错的源代码文件名、函数名称 */ // BSP_Printf("Error: file %s, function %s()\r\n", __FILE__, __FUNCTION__); while(1); /* 参数异常,死机等待看门狗复位 */ } DISABLE_INT(); /* 关中断 */ s_tTmr[_id].Count = 0; /* 实时计数器初值 */ s_tTmr[_id].Flag = 0; /* 定时时间到标志 */ s_tTmr[_id].Mode = TMR_ONCE_MODE; /* 自动工作模式 */ ENABLE_INT(); /* 开中断 */ }
static inline eCC3000States SetState(eCC3000States ns, eCSActions cs) { intState save = DISABLE_INT(); eCC3000States os = sSpiInformation.ulSpiState; sSpiInformation.ulSpiState = ns; switch (cs) { case eAssert: ASSERT_CS(); break; case eDeAssert: DEASSERT_CS(); break; } ENABLE_INT(save); return os; }
static inline int WaitFor(eCC3000States s) { int rv = 1; do { intState save = DISABLE_INT(); rv = (s != sSpiInformation.ulSpiState); // The following handles the race or if the SPiResumeSpi was not called if (rv && s== eSPI_STATE_WRITE_PROCEED && 0==tSLInformation.ReadWlanInterruptPin()) { sSpiInformation.ulSpiState = eSPI_STATE_WRITE_PROCEED; rv = 0; } ENABLE_INT(save); } while(rv && !sSpiInformation.abort); return !sSpiInformation.abort; }
/* ********************************************************************************************************* * 函 数 名: bsp_StartAutoTimer * 功能说明: 启动一个自动定时器,并设置定时周期。 * 形 参: _id : 定时器ID,值域【0,TMR_COUNT-1】。用户必须自行维护定时器ID,以避免定时器ID冲突。 * _period : 定时周期,单位10ms * 返 回 值: 无 ********************************************************************************************************* */ void bsp_StartAutoTimer(uint8_t _id, uint32_t _period) { if (_id >= TMR_COUNT) { /* 打印出错的源代码文件名、函数名称 */ // BSP_Printf("Error: file %s, function %s()\r\n", __FILE__, __FUNCTION__); while(1); /* 参数异常,死机等待看门狗复位 */ } DISABLE_INT(); /* 关中断 */ s_tTmr[_id].Count = _period; /* 实时计数器初值 */ s_tTmr[_id].PreLoad = _period; /* 计数器自动重装值,仅自动模式起作用 */ s_tTmr[_id].Flag = 0; /* 定时时间到标志 */ s_tTmr[_id].Mode = TMR_AUTO_MODE; /* 自动工作模式 */ ENABLE_INT(); /* 开中断 */ }
/* ********************************************************************************************************* * 函 数 名: AD7606_ReadFifo * 功能说明: 从FIFO中读取一个ADC值 * 形 参: _usReadAdc : 存放ADC结果的变量指针 * 返 回 值: 1 表示OK,0表示暂无数据 ********************************************************************************************************* */ uint8_t AD7606_ReadFifo(uint16_t *_usReadAdc) { if (AD7606_HasNewData()) { *_usReadAdc = g_tAdcFifo.sBuf[g_tAdcFifo.usRead]; if (++g_tAdcFifo.usRead >= ADC_FIFO_SIZE) { g_tAdcFifo.usRead = 0; } DISABLE_INT(); if (g_tAdcFifo.usCount > 0) { g_tAdcFifo.usCount--; } ENABLE_INT(); return 1; } return 0; }
// // Assume interrupt is disabled // When this function returns, the interrupt is always enabled because // spk_schedule_task(). // static void spk_dispatch( task_cb* task ) { task_cb* prev; prev = CURRENT_TASK(); CURRENT_TASK() = task; task->status = TASK_ACTIVE; task->wait_obj = NULL; ENABLE_INT(); (task->task)(); DISABLE_INT(); CURRENT_TASK() = prev; // // Dispatch task that has higher priority // spk_schedule_task(); }
/* ********************************************************************************************************* * 函 数 名: DS18B20_Reset * 功能说明: 复位DS18B20。 拉低DQ为低,持续最少480us,然后等待 * 形 参: 无 * 返 回 值: 0 失败; 1 表示成功 ********************************************************************************************************* */ uint8_t DS18B20_Reset(void) { /* 复位时序, 见DS18B20 page 15 首先主机拉低DQ,持续最少 480us 然后释放DQ,等待DQ被上拉电阻拉高,约 15-60us DS18B20 将驱动DQ为低 60-240us, 这个信号叫 presence pulse (在位脉冲,表示DS18B20准备就绪 可以接受命令) 如果主机检测到这个低应答信号,表示DS18B20复位成功 */ uint8_t i; uint16_t k; DISABLE_INT();/* 禁止全局中断 */ /* 复位,如果失败则返回0 */ for (i = 0; i < 1; i++) { DQ_0(); /* 拉低DQ */ bsp_DelayUS(520); /* 延迟 520uS, 要求这个延迟大于 480us */ DQ_1(); /* 释放DQ */ bsp_DelayUS(15); /* 等待15us */ /* 检测DQ电平是否为低 */ for (k = 0; k < 10; k++) { if (DQ_IS_LOW()) { break; } bsp_DelayUS(10); /* 等待65us */ } if (k >= 10) { continue; /* 失败 */ } /* 等待DS18B20释放DQ */ for (k = 0; k < 30; k++) { if (!DQ_IS_LOW()) { break; } bsp_DelayUS(10); /* 等待65us */ } if (k >= 30) { continue; /* 失败 */ } break; } ENABLE_INT(); /* 使能全局中断 */ bsp_DelayUS(5); if (i >= 1) { return 0; } return 1; }
/* ********************************************************************************************************* * 函 数 名: UartSend * 功能说明: 填写数据到UART发送缓冲区,并启动发送中断。中断处理函数发送完毕后,自动关闭发送中断 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ static void UartSend(UART_T *_pUart, uint8_t *_ucaBuf, uint16_t _usLen) { uint16_t i; for (i = 0; i < _usLen; i++) { /* 如果发送缓冲区已经满了,则等待缓冲区空 */ #if 0 /* 在调试GPRS例程时,下面的代码出现死机,while 死循环 原因: 发送第1个字节时 _pUart->usTxWrite = 1;_pUart->usTxRead = 0; 将导致while(1) 无法退出 */ while (1) { uint16_t usRead; DISABLE_INT(); usRead = _pUart->usTxRead; ENABLE_INT(); if (++usRead >= _pUart->usTxBufSize) { usRead = 0; } if (usRead != _pUart->usTxWrite) { break; } } #else /* 当 _pUart->usTxBufSize == 1 时, 下面的函数会死掉(待完善) */ while (1) { uint16_t usCount; DISABLE_INT(); usCount = _pUart->usTxCount; ENABLE_INT(); if (usCount < _pUart->usTxBufSize) { break; } } #endif /* 将新数据填入发送缓冲区 */ _pUart->pTxBuf[_pUart->usTxWrite] = _ucaBuf[i]; DISABLE_INT(); if (++_pUart->usTxWrite >= _pUart->usTxBufSize) { _pUart->usTxWrite = 0; } _pUart->usTxCount++; ENABLE_INT(); } USART_ITConfig(_pUart->uart, USART_IT_TXE, ENABLE); }