#include "buzzer.h"
#include "AI8051U.h"
#include "string.h"

/* AI8051U只有8个 */ 
BuzzerHandleTypeDef buzzer;

static uint16_t period;

static void set_duty(uint16_t duty)
{
	PWMB_CCR7H = (uint8_t)(duty >> 8);	/* 比较值2500 */
	PWMB_CCR7L = (uint8_t)duty;	
}

void buzzer_init()
{
	period = 1000000 / BUZZER_FREQ;
	
	memset(&buzzer, 0, sizeof(BuzzerHandleTypeDef));
	
	P5M0 = 0x00;
	P5M1 = 0x00;
	
	/* P5.2推挽输出 */
    P5M0 |= 0x04;
	P5M1 &= ~0x04; 	
	
	/* IO口电平转换速度设置为最快 */ 
	P5SR &= ~0x04;	

	PWMB_PS = 0x30;
	PWMB_CCER2 = 0x00;	/*清除捕获/比较使能寄存器*/
	PWMB_CCMR3 |= 0x60;	/*捕获/比较模式寄存器*/
	PWMB_CCER2 |= 0x01;
	PWMB_PSCRH = 0x00;	/* 预分频值设置为40 */
	PWMB_PSCRL = 0x28;
	PWMB_ARRH = (uint8_t)(period >> 8);	/* 自动重装载值设置为20000 */
	PWMB_ARRL = (uint8_t)period;
	PWMB_CCR7H = 0;
	PWMB_CCR7L = 0;		
	PWMB_ENO |= 0x10;	/* 输出使能寄存器 */
	PWMB_BKR |= 0x80;	/* 使能主输出 */
	PWMB_CR1 |= 0x01;	/* 开始计时 */
}

void buzzer_on()
{
	buzzer.ticks_on = 1;
	buzzer.ticks_off = 0;
	buzzer.times = 0;
	buzzer.status = BUZZER_START_NEW_CYCLE;
}


void buzzer_off()
{
	buzzer.ticks_on = 0;
	buzzer.ticks_off = 0;
	buzzer.times = 0;
	buzzer.status = BUZZER_START_NEW_CYCLE;
}

void buzzer_toggle(uint32_t ticks_on, uint32_t ticks_off, uint16_t times)
{
	buzzer.ticks_on = ticks_on;
	buzzer.ticks_off = ticks_off;
	buzzer.times = times;
	buzzer.status = BUZZER_START_NEW_CYCLE;	
}

void buzzer_handler()
{
    switch(buzzer.status)
	{
        case BUZZER_START_NEW_CYCLE:
            if(buzzer.ticks_on > 0)
			{
                set_duty(period / 2);
                if(buzzer.ticks_off > 0)
				{ /* 熄灭时间不为 0 即为 闪烁否则为长亮 */
                    buzzer.ticks_count = 0;
                    buzzer.status = BUZZER_WATTING_OFF; /* 等待 LED 灯亮起时间结束 */
                }
				else
				{
					buzzer.status = BUZZER_IDLE; /* 长亮， 转入空闲 */
				}
            }
			else
			{ /* 只要亮起时间为 0 即为长灭 */
                set_duty(0);
				buzzer.status = BUZZER_IDLE; /* 长灭， 转入空闲 */
            }
            break;
			
        case BUZZER_WATTING_OFF:
            buzzer.ticks_count += BUZZER_TIMER_PERIOD;
            if(buzzer.ticks_count >= buzzer.ticks_on)
			{ /* LED 亮起时间结束 */
                set_duty(0);
                buzzer.status = BUZZER_WATTING_PERIOD_END;
            }
            break;

        case BUZZER_WATTING_PERIOD_END:	/* 等待周期结束 */
            buzzer.ticks_count += BUZZER_TIMER_PERIOD;
            if(buzzer.ticks_count >= (buzzer.ticks_off + buzzer.ticks_on))
			{
				buzzer.ticks_count -= (buzzer.ticks_off + buzzer.ticks_on);
                if(buzzer.times == 1)
				{ /* 剩余重复次数为1时就可以结束此次控制任务 */
                    set_duty(0);
                    buzzer.status = BUZZER_IDLE;  /* 重复次数用完， 转入空闲 */
                }
				else
				{
                    set_duty(period / 2);
                    buzzer.times = buzzer.times == 0 ? 0 : buzzer.times - 1;
                    buzzer.status = BUZZER_WATTING_OFF;
                }
            }
            break;

        case BUZZER_IDLE:
            break;
		
        default:
            break;
    }
}