/*************************************************************************
	> File Name: 74hc595.c
	> Author: ma6174
	> Mail: ma6174@163.com 
	> Created Time: 2023/9/20 17:48:24
 ************************************************************************/

#include  "bsp_74hc595.h"
#include  <stdlib.h>
#include  <stdio.h>
#include  <stdint.h>


#define DS_MOS(a)	if (a)	\
    gpio_bits_set(GPIOB, GPIO_PINS_14);\
    else		\
    gpio_bits_reset(GPIOB, GPIO_PINS_14)						

#define SHCP_MOS(a)	if (a)	\
    gpio_bits_set(GPIOA, GPIO_PINS_8);\
    else		\
    gpio_bits_reset(GPIOA, GPIO_PINS_8)						

#define STCP_MOS(a)	if (a)	\
    gpio_bits_set(GPIOB, GPIO_PINS_15);\
    else		\
    gpio_bits_reset(GPIOB, GPIO_PINS_15)
		
#define OE_MOS(a)	if (a)	\
    gpio_bits_set(GPIOB, GPIO_PINS_13);\
    else		\
    gpio_bits_reset(GPIOB, GPIO_PINS_13)
		
#define MR_MOS(a)	if (a)	\
    gpio_bits_set(GPIOA, GPIO_PINS_7);\
    else		\
    gpio_bits_reset(GPIOA, GPIO_PINS_7)
		
inline void ic_74hc595_delay(uint32_t num)
{
    while(num --);
}

void ic_74hc595_init(void)
{
		gpio_init_type gpio_init_struct;

		/* enable the led clock */
		crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK,TRUE);
		crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK,TRUE);

		/* set default parameter */
		gpio_default_para_init(&gpio_init_struct);

		/* configure the led gpio */
		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_OUTPUT;
		gpio_init_struct.gpio_pins = GPIO_PINS_8;
		gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
		gpio_init(GPIOA, &gpio_init_struct);
	
		gpio_init_struct.gpio_pins = GPIO_PINS_13 | GPIO_PINS_14 | GPIO_PINS_15;
		gpio_init(GPIOB, &gpio_init_struct);
		ic_74hc595_clean_0(32);
}

//移位寄存器某个引脚输出1，其他引脚输出0;
//因为硬件是反相器，所以适应低扫
void ic_74hc595_io_write_1(uint8_t io_num)
{
	
		DS_MOS(1);
		SHCP_MOS(1);
		ic_74hc595_delay(1);
		SHCP_MOS(0);
	
		for(uint8_t i = 0; i < io_num; i++)
    {
			DS_MOS(0);
    	SHCP_MOS(1);
    	ic_74hc595_delay(1);
	  	SHCP_MOS(0);
	  	ic_74hc595_delay(1);
	  }
	  STCP_MOS(1);
	  ic_74hc595_delay(1);
		STCP_MOS(0);
}

//移位寄存器某个引脚输出0,其他引脚输出1；
//因为硬件是反相器，所以适应高扫
void ic_74hc595_io_write_0(uint8_t io_num)
{
		DS_MOS(0);
		SHCP_MOS(1);
		ic_74hc595_delay(1);
		SHCP_MOS(0);
	
		for(uint8_t i = 0; i < io_num; i++)
    {
			DS_MOS(1);
    	SHCP_MOS(1);
    	ic_74hc595_delay(1);
	  	SHCP_MOS(0);
	  	ic_74hc595_delay(1);
	  }
	  STCP_MOS(1);
	  ic_74hc595_delay(1);
		STCP_MOS(0);
}
//移位寄存器所有引脚全输出0
//因为硬件是反相器，所以适应低扫
void ic_74hc595_clean_0(uint8_t io_num)
{
		DS_MOS(0);
		SHCP_MOS(0);
		STCP_MOS(0);
		
		for(uint8_t i = 0; i < io_num; i++)
		 {     
					SHCP_MOS(1);
					ic_74hc595_delay(1);

          //变为低电平，为下次准备
					SHCP_MOS(0);
					ic_74hc595_delay(1);
		 }  
		 
		 STCP_MOS(1);
		 ic_74hc595_delay(1);
		 STCP_MOS(0);
}

//移位寄存器所有引脚全输出1;
//因为硬件是反相器，所以适应高扫
void ic_74hc595_clean_1(uint8_t io_num)
{
		DS_MOS(1);
		SHCP_MOS(0);
		STCP_MOS(0);
		
		for(uint8_t i = 0; i < io_num; i++)
		 {     
					SHCP_MOS(1);
					ic_74hc595_delay(1);

          //变为低电平，为下次准备
					SHCP_MOS(0);
					ic_74hc595_delay(1);
		 }  
		 
		 STCP_MOS(1);
		 ic_74hc595_delay(1);
		 STCP_MOS(0);
}

void ic_74hc595_wirte_32bit(uint32_t data)
{
		DS_MOS(0);
		SHCP_MOS(0);
		STCP_MOS(0);
		uint32_t temp = 0;
		for(uint8_t i = 0; i < 32; i++)
		{
				temp = data & (0x80000000>>i);
				DS_MOS(temp);
				SHCP_MOS(1);
				ic_74hc595_delay(1);
				SHCP_MOS(0);
				ic_74hc595_delay(1);
		}
		STCP_MOS(1);
		ic_74hc595_delay(1);
		STCP_MOS(0);
}

