ChipTest/PAN159/PAN159-Template/Library/StdDriver/driver/lib_driver_swiic_pan159.c
2021-09-26 17:19:12 +08:00

380 lines
16 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*******************************************************************************
* @note Copyright (C) 2017 Shanghai Panchip Microelectronics Co., Ltd.
* All rights reserved.
*
* @file driver_swiic_pan159.c
* @brief PAN159 GPIO IICͨÓÃÇý¶¯
*
* @history - V1.0, 2017-08-25, xiaoguolin, first implementation.
*******************************************************************************/
#include "lib_driver_swiic_pan159.h"
#include "string.h"
#define __swiic_pan159_delay __delay_pan159
#define __swiic_pan159_mutex_lock(hiic) __disable_irq()
#define __swiic_pan159_mutex_unlock(hiic) __enable_irq()
#define __swiic_pan159_read_sda(hiic) (*((hiic)->sda))
#define __swiic_pan159_write_sda(hiic,val) (*((hiic)->sda)=(val))
#define __swiic_pan159_write_scl(hiic,val) (*((hiic)->scl)=(val))
#define __swiic_pan159_set_speed(hiic,spd) ((hiic)->speed.code=(spd))
#define __swiic_pan159_get_speed(hiic) ((hiic)->speed.code)
//#define __swiic_pan159_echo_wclk(hiic) \
// do{ \
// __swiic_pan159_delay((hiic)->speed.scl_tim_code.l); \
// __swiic_pan159_write_scl((hiic),1); \
// __swiic_pan159_delay((hiic)->scl_tim_code_h); \
// __swiic_pan159_write_scl((hiic),0); \
// __swiic_pan159_delay((hiic)->speed.scl_tim_code.l); \
// }while(0)
void __swiic_pan159_echo_wclk(const swiic_pan159_t* hiic)
{
__swiic_pan159_delay(hiic->speed.scl_tim_code.l);
__swiic_pan159_write_scl(hiic,1);
__swiic_pan159_delay(hiic->speed.scl_tim_code.h);
__swiic_pan159_write_scl(hiic,0);
__swiic_pan159_delay(hiic->speed.scl_tim_code.l);
}
#define __swiic_pan159_echo_rclk(hiic,pret) \
do{ \
__swiic_pan159_delay((hiic)->speed.scl_tim_code.l); \
__swiic_pan159_write_scl((hiic),1); \
__swiic_pan159_delay((hiic)->speed.scl_tim_code.l); \
*(pret) = __swiic_pan159_read_sda((hiic)); \
__swiic_pan159_write_scl((hiic),0); \
__swiic_pan159_delay((hiic)->speed.scl_tim_code.l); \
}while(0)
/**
* IIC START SIGNAL:
* ___
* SDA \_______
* ______
* SCL / \___
*/
//#define __swiic_pan159_start(hiic) \
// do{ \
// __swiic_pan159_write_sda((hiic),1); \
// __swiic_pan159_write_scl((hiic),1); \
// __swiic_pan159_delay((hiic)->speed.scl_tim_code.l); \
// __swiic_pan159_write_sda((hiic),0); \
// __swiic_pan159_delay((hiic)->speed.scl_tim_code.l); \
// __swiic_pan159_write_scl((hiic),0); \
// __swiic_pan159_delay((hiic)->speed.scl_tim_code.l); \
// }while(0)
void __swiic_pan159_start(const swiic_pan159_t* hiic)
{
__swiic_pan159_write_sda(hiic,1);
__swiic_pan159_write_scl(hiic,1);
__swiic_pan159_delay(hiic->speed.scl_tim_code.l);
__swiic_pan159_write_sda(hiic,0);
__swiic_pan159_delay(hiic->speed.scl_tim_code.l);
__swiic_pan159_write_scl(hiic,0);
__swiic_pan159_delay(hiic->speed.scl_tim_code.l);
}
/**
* IIC STOP SIGNAL:
* ___
* SDA ___/
* ______
* SCL /
*/
//#define __swiic_pan159_stop(hiic) \
// do{ \
// __swiic_pan159_write_sda((hiic),0); \
// __swiic_pan159_write_scl((hiic),1); \
// __swiic_pan159_delay((hiic)->scl_tim_code_l); \
// __swiic_pan159_write_sda((hiic),1); \
// }while(0)
void __swiic_pan159_stop(const swiic_pan159_t* hiic)
{
__swiic_pan159_write_sda(hiic,0);
__swiic_pan159_write_scl(hiic,1);
__swiic_pan159_delay(hiic->speed.scl_tim_code.l);
__swiic_pan159_write_sda(hiic,1);
}
/**
* IIC ACK SIGNAL:
* _
* SDA \___________/
* ____
* SCL ___/ \_____
*/
#define __swiic_pan159_write_ack(hiic) \
do{ \
__swiic_pan159_write_sda((hiic),0); \
__swiic_pan159_echo_wclk((hiic)); \
__swiic_pan159_write_sda((hiic),1); \
}while(0)
/**
* IIC NACK SIGNAL:
* ____________
* SDA
* ____
* SCL ___/ \___
*/
#define __swiic_pan159_write_nack(hiic) \
do{ \
__swiic_pan159_write_sda((hiic),1); \
__swiic_pan159_echo_wclk((hiic)); \
}while(0)
void __swiic_pan159_write_byte(const swiic_pan159_t *hiic, uint8_t _ubyte)
{
register uint8_t ubyte = _ubyte;
register uint8_t i;
for(i = 0; i < 8; i++){
__swiic_pan159_write_sda(hiic,((ubyte & 0x80) ? 1 : 0));
__swiic_pan159_echo_wclk(hiic);
ubyte <<= 1;
}
}
uint8_t __swiic_pan159_read_byte(const swiic_pan159_t* hiic)
{
register uint8_t ubyte = 0;
register uint8_t i;
for(i = 0; i < 8; i++){
ubyte <<= 1;
__swiic_pan159_delay(hiic->speed.scl_tim_code.l);
__swiic_pan159_write_scl(hiic,1);
__swiic_pan159_delay(hiic->speed.scl_tim_code.l);
ubyte |= __swiic_pan159_read_sda(hiic);
__swiic_pan159_write_scl(hiic,0);
__swiic_pan159_delay(hiic->speed.scl_tim_code.l);
}
return ubyte;
}
uint8_t __swiic_pan159_read_ack(const swiic_pan159_t* hiic)
{
uint8_t ret;
__swiic_pan159_write_sda(hiic,1);
__swiic_pan159_echo_rclk(hiic,&ret);
return ret;
}
/*******************************************************************************
* @brief GPIO IIC³õʼ»¯
* @param[in] hiic - IICÉ豸¾ä±ú
* iic_speed - IICËÙÂÊ
* sda_port_n - SDA¶Ë¿ÚºÅ
* sda_pin_n - SDAÒý½ÅºÅ
* scl_port_n - SCL¶Ë¿ÚºÅ
* scl_pin_n - SCLÒý½ÅºÅ
* @return 1 - ³É¹¦, 0 - ʧ°Ü
* @history - V1.0, 2017-08-25, xiaoguolin, first implementation.
*******************************************************************************/
void swiic_pan159_init(swiic_pan159_t* hiic, uint32_t iic_speed,
uint32_t sda_port_n, uint32_t sda_pin_n,
uint32_t scl_port_n, uint32_t scl_pin_n)
{
hiic->sda = &GPIO_PIN_ADDR(sda_port_n,sda_pin_n);
hiic->scl = &GPIO_PIN_ADDR(scl_port_n,scl_pin_n);
/**
* us * 6 - 4 = code
* ʱÖÓ·Ö²¼Îª low : high = 2 : 1, Òò´Ë·ÖΪ 3 ·Ý
* ______
* \______ ______/ \
* low - 2 high - 1
* Òò´Ëcode = us * 2 - 1
*/
__swiic_pan159_set_speed(hiic, iic_speed);
#define __PORT__(n) ((GPIO_T *) (AHBPERIPH_BASE + (0x04000 | ((n) << 6))))
#define __PIN__(n) (1 << (n))
GPIO_SetMode(__PORT__(sda_port_n),__PIN__(sda_pin_n),GPIO_MODE_OPEN_DRAIN);
GPIO_SetMode(__PORT__(scl_port_n),__PIN__(scl_pin_n),GPIO_MODE_OPEN_DRAIN);
#undef __PORT__
#undef __PIN__
__swiic_pan159_stop(hiic);
}
/*******************************************************************************
* @brief GPIO IIC¶ÁÈ¡(¸Ãº¯Êý¶ÁÈ¡¾ßÓÐÒ»¶¨µÄ·çÏÕ,ÎÞ·¨Çø·Ö¶Áȡʧ°ÜºÍ¶Áµ½0)
* @param[in] dhiic - Ä¿±êIICÉ豸¾ä±ú
* shiic - Ô´IICÉ豸¾ä±ú
* iic_speed - IICËÙÂÊ
* @return ÎÞ
* @history - V1.0, 2017-09-12, xiaoguolin, first implementation.
*******************************************************************************/
void swiic_pan159_copy(swiic_pan159_t* dhiic, const swiic_pan159_t* shiic, uint32_t iic_speed)
{
memcpy(dhiic,shiic,sizeof(swiic_pan159_t));
if(iic_speed != SWIIC_PAN159_SPEED_SYS_48M_IIC_DEFAULT){
__swiic_pan159_set_speed(dhiic,iic_speed);
}
}
/*******************************************************************************
* @brief GPIO IIC¶ÁÈ¡(¸Ãº¯Êý¶ÁÈ¡¾ßÓÐÒ»¶¨µÄ·çÏÕ,ÎÞ·¨Çø·Ö¶Áȡʧ°ÜºÍ¶Áµ½0)
* @param[in] hiic - IICÉ豸¾ä±ú
* iic_speed - IICËÙÂÊ
* dev - IICÉ豸µØÖ·
* reg - ¼Ä´æÆ÷µØÖ·
* @return ¶ÁÈ¡µ½µÄ×Ö½Ú
* @history - V1.0, 2017-08-25, xiaoguolin, first implementation.
*******************************************************************************/
uint8_t swiic_pan159_read_byte(const swiic_pan159_t* hiic, uint8_t dev, uint8_t reg)
{
register uint8_t ret = 0;
__swiic_pan159_mutex_lock(hiic); /* Ëø¶¨MUTEX */
__swiic_pan159_start(hiic); /* Æô¶¯IIC */
__swiic_pan159_write_byte(hiic,(dev << 1)|0); /* дÉ豸µØÖ·(д) */
if(__swiic_pan159_read_ack(hiic) == 0){ /* ¶ÁÈ¡ACK */
__swiic_pan159_write_byte(hiic,reg); /* д¼Ä´æÆ÷µØÖ· */
if(__swiic_pan159_read_ack(hiic) == 0){ /* ¶ÁÈ¡ACK */
__swiic_pan159_start(hiic); /* ÖØÆôIIC */
__swiic_pan159_write_byte(hiic,(dev << 1)|1); /* дÉ豸µØÖ·(¶Á) */
if(__swiic_pan159_read_ack(hiic) == 0){ /* ¶ÁÈ¡ACK */
ret = __swiic_pan159_read_byte(hiic); /* ¶ÁÈ¡Êý¾Ý×Ö½Ú */
__swiic_pan159_write_nack(hiic); /* »ØдNACK */
} /* */
} /* */
} /* */
__swiic_pan159_stop(hiic); /* ֹͣIIC */
__swiic_pan159_mutex_unlock(hiic); /* ÊÍ·ÅMUTEX */
return ret;
}
/*******************************************************************************
* @brief GPIO IIC¶ÁÈ¡
* @param[in] hiic - IICÉ豸¾ä±ú
* iic_speed - IICËÙÂÊ
* dev - IICÉ豸µØÖ·
* reg - ¼Ä´æÆ÷µØÖ·
* len - Òª¶ÁÈ¡µÄÊý¾Ý³¤¶È
* @param[out] _buf - Êý¾Ý»º³åÇø
* @return ¶ÁÈ¡µ½µÄ×Ö½ÚÊý
* @history - V1.0, 2017-08-25, xiaoguolin, first implementation.
*******************************************************************************/
uint32_t swiic_pan159_read_bytes(const swiic_pan159_t* hiic, uint8_t dev, uint8_t reg, uint8_t* buf, uint32_t len)
{
register uint32_t i = 0;
__swiic_pan159_mutex_lock(hiic); /* Ëø¶¨MUTEX */
__swiic_pan159_start(hiic); /* Æô¶¯IIC */
__swiic_pan159_write_byte(hiic,(dev << 1)|0); /* дÉ豸µØÖ·(д) */
if(__swiic_pan159_read_ack(hiic) == 0){ /* ¶ÁÈ¡ACK */
__swiic_pan159_write_byte(hiic,reg); /* д¼Ä´æÆ÷µØÖ· */
if(__swiic_pan159_read_ack(hiic) == 0){ /* ¶ÁÈ¡ACK */
__swiic_pan159_start(hiic); /* ÖØÆôIIC */
__swiic_pan159_write_byte(hiic,(dev << 1)|1); /* дÉ豸µØÖ·(¶Á) */
if(__swiic_pan159_read_ack(hiic) == 0){ /* ¶ÁÈ¡ACK */
for(len--; i < len; i++){ /* lenÖмõµô¶ÁÈ¡Êý¾ÝÖеÄ×îºóÒ»¸ö×Ö½Ú */
buf[i] = __swiic_pan159_read_byte(hiic); /* ¶ÁÈ¡×Ö½Ú */
__swiic_pan159_write_ack(hiic); /* »ØдACK */
} /* */
buf[i++] = __swiic_pan159_read_byte(hiic); /* ¶ÁÈ¡×îºóÒ»¸ö×Ö½Ú */
__swiic_pan159_write_nack(hiic); /* »ØдNACK */
} /* */
} /* */
} /* */
__swiic_pan159_stop(hiic); /* ֹͣIIC */
__swiic_pan159_mutex_unlock(hiic); /* ÊÍ·ÅMUTEX */
return i;
}
/*******************************************************************************
* @brief GPIO IICдÈë
* @param[in] hiic - IICÉ豸¾ä±ú
* iic_speed - IICËÙÂÊ
* dev - IICÉ豸µØÖ·
* reg - ¼Ä´æÆ÷µØÖ·
* ubyte - ´ýдÈë×Ö½Ú
* @return 1 - ³É¹¦
* 0 - ʧ°Ü
* @history - V1.0, 2017-08-25, xiaoguolin, first implementation.
*******************************************************************************/
uint8_t swiic_pan159_write_byte(const swiic_pan159_t* hiic, uint8_t dev, uint8_t reg, uint8_t ubyte)
{
__swiic_pan159_mutex_lock(hiic); /* Ëø¶¨MUTEX */
__swiic_pan159_start(hiic); /* Æô¶¯IIC */
__swiic_pan159_write_byte(hiic,(dev << 1)|0); /* дÉ豸µØÖ·(д) */
if(__swiic_pan159_read_ack(hiic) == 0){ /* ¶ÁÈ¡ACK */
__swiic_pan159_write_byte(hiic,reg); /* д¼Ä´æÆ÷µØÖ· */
if(__swiic_pan159_read_ack(hiic) == 0){ /* ¶ÁÈ¡ACK */
__swiic_pan159_write_byte(hiic,ubyte); /* д×Ö½ÚÊý¾Ý */
ubyte = (__swiic_pan159_read_ack(hiic) == 0) ? 1 : 0; /* ¶ÁÈ¡ACK */
} /* */
} /* */
__swiic_pan159_stop(hiic); /* ֹͣIIC */
__swiic_pan159_mutex_unlock(hiic); /* ÊÍ·ÅMUTEX */
return ubyte;
}
/*******************************************************************************
* @brief GPIO IICдÈë
* @param[in] hiic - IICÉ豸¾ä±ú
* iic_speed - IICËÙÂÊ
* dev - IICÉ豸µØÖ·
* reg - ¼Ä´æÆ÷µØÖ·
* buf - Êý¾Ý»º³åÇø
* len - ҪдÈëµÄÊý¾Ý³¤¶È
* @return дÈëµÄ×Ö½ÚÊý
* @history - V1.0, 2017-08-25, xiaoguolin, first implementation.
*******************************************************************************/
uint32_t swiic_pan159_write_bytes(const swiic_pan159_t* hiic, uint8_t dev, uint8_t reg, const uint8_t* buf, uint32_t len)
{
register uint32_t i = 0;
__swiic_pan159_mutex_lock(hiic); /* Ëø¶¨MUTEX */
__swiic_pan159_start(hiic); /* Æô¶¯IIC */
__swiic_pan159_write_byte(hiic,(dev << 1)|0); /* дÉ豸µØÖ·(д) */
if(__swiic_pan159_read_ack(hiic) == 0){ /* ¶ÁÈ¡ACK */
__swiic_pan159_write_byte(hiic,reg); /* д¼Ä´æÆ÷µØÖ· */
if(__swiic_pan159_read_ack(hiic) == 0){ /* ¶ÁÈ¡ACK */
for(; i < len; i++){ /* */
__swiic_pan159_write_byte(hiic,buf[i]); /* д×Ö½ÚÊý¾Ý */
if(__swiic_pan159_read_ack(hiic) != 0){ /* ¶ÁÈ¡ACK */
break; /* */
} /* */
} /* */
} /* */
} /* */
__swiic_pan159_stop(hiic); /* ֹͣIIC */
__swiic_pan159_mutex_unlock(hiic); /* ÊÍ·ÅMUTEX */
return i;
}
swiic_pan159_t imu_iic;
swiic_pan159_t bar_iic;
//typedef void (*TCallback)(void);
void iic_pan159_init(void)
{
swiic_pan159_init(&imu_iic,0x00030003,3,4,3,5);
swiic_pan159_copy(&bar_iic,&imu_iic,0x00030003);
}
void iic_start_send_bytes(uint16_t devAddr,uint8_t regAddr, uint8_t *buf, uint8_t len,TCallback cbk, TCallback fail_cbk)
{
if(swiic_pan159_write_bytes(&imu_iic, devAddr, regAddr, buf, len)){
if(cbk){
cbk();
}
}
else{
if(fail_cbk){
fail_cbk();
}
}
}
void iic_start_read_bytes(uint16_t devAddr,uint8_t regAddr, uint8_t *buf, uint8_t len,TCallback cbk, TCallback fail_cbk)
{
if(swiic_pan159_read_bytes(&imu_iic, devAddr, regAddr, buf, len)){
if(cbk){
cbk();
}
}
else{
if(fail_cbk){
fail_cbk();
}
}
}