JAJA751A june   2020  – may 2023 BQ25150 , BQ25155 , BQ25618 , BQ25619 , TS5A12301E , TS5A3157 , TS5A3159A , TS5A6542

 

  1.   1
  2. ピン・インターフェイスを使用した TWS の高効率充電
  3.   商標
  4. はじめに
  5. システム概要
    1. 2.1 充電ケース
      1. 2.1.1 BQ25619
      2. 2.1.2 TLV62568P
      3. 2.1.3 TPS22910A
      4. 2.1.4 TS5A12301E
      5. 2.1.5 マイコン
    2. 2.2 イヤホン
      1. 2.2.1 BQ25155
      2. 2.2.2 TPS22910A
      3. 2.2.3 TS5A12301E
      4. 2.2.4 BT/SOC
  6. 充電ケース・アルゴリズムの実装
    1. 3.1 初期化とメイン・コード
    2. 3.2 UART 割り込みおよび出力電圧の調整
  7. イヤホン・アルゴリズムの実装
    1. 4.1 初期化とメイン・コード
    2. 4.2 割り込みと送信
  8. テスト方法
  9. テスト結果
    1. 6.1 動的電圧の調整
    2. 6.2 出力 4.6V の BQ25619
    3. 6.3 出力 5V の標準昇圧
  10. まとめ
  11. 回路図
  12. PCB レイアウト
  13. 10ソフトウェア
    1. 10.1 充電ケース main.c
    2. 10.2 イヤホン main.c
  14. 11改訂履歴

充電ケース main.c

/* --COPYRIGHT--,BSD
 * Copyright (c) 2016, Texas Instruments Incorporated
 * All rights reserved.
 *
 * 修正のあるなしに関わらず、ソース形式またはバイナリ形式での
 * 再配布および使用は、以下の条件を満たしている場合に
 * 許可されます。
 *
 * *  ソース・コードの再配布は上記の著作権表示、この条件のリスト
 *    および以下の免責事項を保持している必要があります。
 *
 * *  バイナリ形式での再配布は上記の著作権表示、この条件のリスト
 *    、および以下の免責事項を配布に付属のドキュメント
 *    および / またはその他の資料に再現する必要があります。
 *
 * *  テキサス・インスツルメンツまたはその貢献者のいずれの名前も
 *    特に事前の書面による許可なく、本ソフトウェアに由来の
 *    製品を宣伝または販売促進することはできません。
 *
 * 本ソフトウェアはその著作権保有者およびその貢献者により「現状のまま」提供され、
 * 明示あるいは黙示を問わず、これに限定されることなく
 * 商品性の黙示保証、特定目的への適合性に対して
 * 一切保証しないものとします。いかなる場合にも、著作権保有者または
 * 貢献者は、直接的、間接的、付随的、特別、拡大、懲罰的または結果的損害
 * (商品またはサービスの代替品の調達、使用、データ、または利益の逸失
 * または業務の中断を含むがこれに限りません)
 * の可能性を忠告されていたにもかかわらず本ソフトウェアの使用により生じた
 * 当該損害について、その原因を問わず
 * 契約上の責任、厳格責任、または不法行為責任 (その他の過失を含む) 
 * の法理に基づいて、一切の責任を負わないものとします。
 * --/COPYRIGHT--*/
/*
 * ======== main.c ========
*/
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
#include <stdio.h>
#include "board_functions.h"
#include <stdlib.h>
#include "driverlib.h"
#include "StdI2C.h"
#include "BQ25150.h"
//#include "board_timer.h"
#include "USB_config/descriptors.h"
#include "USB_API/USB_Common/device.h"
#include "USB_API/USB_Common/usb.h"                 // USB 固有の関数
#include "USB_API/USB_CDC_API/UsbCdc.h"
#include "USB_app/usbConstructs.h"
#include "OLED/Oled_SSD1306.h"
#include "StdPollI2C.h"
//#include <Wire.h>
/*
 * your own board.
 */
#include "hal.h"
//#include "Energia.h"
//#include "pins_energia.h"
// 関数の宣言
uint8_t retInString(char* string);
void initTimer(void);
void setTimer_A_Parameters(void);
// イベントによって設定されたグローバル・フラグ
volatile uint8_t bCDCDataReceived_event = FALSE; // open rx 演算なくデータが rx された
// ことを示します
char str[50];
#define NUM_SAMPLES 8
#define clkspeed 3          // 24Mhz クロック選択
//#define clkspeed 1        // 8Mhz クロック選択
short samples[NUM_SAMPLES] ;
int sample_index = 0 ;
char str[50];
char cmdstring[5];
char cs2[3];
uint8_t response = 0;
//unsigned char buffer[10]={1,2,3,4,5,6,7,8,9,10};
volatile char wholeString[MAX_STR_LENGTH] = "";
volatile uint8_t modecounter = 0;
volatile uint8_t pluscounter = 0;
///Timer_A_initUpModeParam Timer_A_params = {0};
int i;
unsigned char* PRxData;                     // RX データへのポインタ
unsigned char RXByteCtr;
volatile unsigned char RxBuffer[128];       // 128 バイトの RAM を割り当てます
unsigned char* PTxData;                     // TX データへのポインタ
unsigned char TXByteCtr;
const unsigned char TxData[] =              // 転送するデータのテーブル
{
 0x11,
 0x22,
 0x33,
 0x44,
 0x55
};
volatile uint8_t Button_Released = 0;
unsigned int result;
const char* hexstring = "0xabcdef0";
int raddr;
int rdata;
char buf[5];
uint8_t uraddr;
uint8_t urdata;
uint16_t Err;
// 発信文字列を保持します
char outString[MAX_STR_LENGTH] = "";
uint8_t connectedflag = 0;
uint8_t echoflag = 1;
int ubtncounter = 0;
uint8_t RegValuesL = 0;
uint8_t RegValuesM = 0;
uint8_t RegValueMSB = 0;
uint8_t ADCCheck = 0;
uint32_t stobusf;
char vBat;
char vBatString;
uint32_t stobuf;
uint32_t stobuf1;
double stobuf2;
double PwmDuty;
uint8_t RegValues = 0;
double batteryVoltageCheck = 0;
//__delay_cycles(1000); 1000 = 100us
uint8_t rthex;
// トグル遅延を設定 / 宣言します
//uint16_t SlowToggle_Period = 20000 - 1;
//uint16_t FastToggle_Period = 1000 - 1;
//  ======== main ========
void main(void)
{
    WDT_A_hold(WDT_A_BASE); // ウォッチドッグ・タイマを停止します
    // USB API に必要な最低 Vcore 設定は PMM_CORE_LEVEL_2 です。
    PMM_setVCore(PMM_CORE_LEVEL_2);
    USBHAL_initPorts();           // ローパワー (出力 Low) の GPIOS を構成します
    USBHAL_initClocks(8000000 * clkspeed);   // クロックを構成します。MCLK=SMCLK=FLL=8MHz; ACLK=REFO=32kHz
    initTimer();           // LED トグルのタイマを準備します
    initI2C();
//  ======== UART Setup ========
    GPIO_setAsInputPinWithPullDownResistor(GPIO_PORT_P3,GPIO_PIN4); // P3.4 = Input With pulldown
    P3SEL = BIT3+BIT4;                        // P3.4,5 = USCI_A0 TXD/RXD
    UCA0CTL1 |= UCSWRST;                      // **ステート・マシンをリセットにします**
    UCA0CTL1 |= UCSSEL_2;                     // SMCLK
    UCA0BR0 = 6;                              // 1MHz 9600 (ユーザー・ガイドを参照)
    UCA0BR1 = 0;                              // 1MHz 9600
    UCA0MCTL = UCBRS_0 + UCBRF_13 + UCOS16;   // Modln UCBRSx=0, UCBRFx=0,
                                              // オーバー・サンプリング
    UCA0CTL1 &= ~UCSWRST;                     // **USCI ステート・マシンを初期化します**
//  ======== GPIO Setup ========
    GPIO_setAsOutputPin(LED_4);
    GPIO_setOutputLowOnPin(LED_4);
    GPIO_setAsInputPin(CASE_PMID_GOOD);
    GPIO_setAsInputPinWithPullUpResistor(CASE_INT);
    GPIO_setAsInputPin(CASE_BUCK_PG);
    GPIO_setAsInputPinWithPullUpResistor(CASE_START);
    GPIO_setAsOutputPin(CASE_FB);
    GPIO_setOutputLowOnPin(CASE_FB);
    GPIO_setAsOutputPin(CASE_PSEL);
    GPIO_setOutputLowOnPin(CASE_PSEL);
    GPIO_setAsOutputPin(CASE_QON);
    GPIO_setOutputHighOnPin(CASE_QON);
    GPIO_setAsOutputPin(CASE_CE);
    GPIO_setOutputLowOnPin(CASE_CE);
    GPIO_setAsOutputPin(CASE_G1);
    GPIO_setOutputLowOnPin(CASE_G1);
    GPIO_setAsOutputPin(LED_5);
    GPIO_setOutputLowOnPin(LED_5);
//    GPIO_setAsOutputPin(LED_6);
//    GPIO_setOutputLowOnPin(LED_6);
//  ======== PWM Setup ========
    P2DIR |= BIT5; //ピン 2.5 を出力方向に設定します。
    P2SEL |= BIT5; //ピン 2.5 を当社の PWM 出力として選択します。
    TA2CCTL2 = OUTMOD_7;
    TA2CCR0 = 40; //タイマ A0 Capture/Compare 0 レジスタの期間を 40us に設定します。
    TA2CCR2 = 14; //電源がオンの時間 (ミリ秒)、デフォルト 14 = 35%, ~= 4.5v OUTPUT
    TA2CTL = (TASSEL_2 | MC_1); //TASSEL_2 は SMCLK をクロック・ソースとして選択し、MC_1 は TA0CCR0 の値をカウントするよう通知します。
 //  ======== BQ25619 Register Setup ========
    StdI2C_P_TX_Single(BQ25619_ADDR, BQ25619_REG01, 0x3A, &Err); // BST_CONFIG = 1, Boost mode Enable, REG01 = 01h, value = 0x3A
    StdI2C_P_RX_Single(BQ25619_ADDR, BQ25619_REG01, &RegValues, &Err);
    StdI2C_P_TX_Single(BQ25619_ADDR, BQ25619_REG05, 0x8E, &Err); // ウォッチドッグをディスエーブルにします
    StdI2C_P_RX_Single(BQ25619_ADDR, BQ25619_REG05, &RegValues, &Err);
    StdI2C_P_TX_Single(BQ25619_ADDR, BQ25619_REG06, 0xC6, &Err); // 昇圧電圧を 0xE6 =  5V に設定し、0xC6 の場合は 4.6V
    StdI2C_P_RX_Single(BQ25619_ADDR, BQ25619_REG06, &RegValues, &Err);
    GPIO_setOutputHighOnPin(LED_4);
    waitms(500);
    GPIO_setOutputLowOnPin(LED_4);
    waitms(500);
//  ======== Ready while loop ========
    //この while ループは割り込みをディスエーブルした状態でプログラムを保持します。これによりイヤホンと同期できます
    //BQ_START ピン 4.3 をグランドに短絡させてループを終了します
    while(GPIO_getInputPinValue(CASE_START) == 1)
    {
        GPIO_toggleOutputOnPin(LED_5);
        __delay_cycles(3000000);
        GPIO_toggleOutputOnPin(LED_5);
        __delay_cycles(3000000);
        GPIO_toggleOutputOnPin(LED_5);
        __delay_cycles(3000000);
        GPIO_toggleOutputOnPin(LED_5);
        __delay_cycles(15000000);
    }
    GPIO_setOutputLowOnPin(LED_5);
//  ======== Interrupt Enables ========
    __enable_interrupt();  // 割り込みをグローバルにイネーブルします
    UCA0IE |= UCRXIE;
//  ======== Main while loop ========
    //通信サイクル時間を調整できます
    while(1)
    {
        GPIO_toggleOutputOnPin(LED_4);
//        __delay_cycles(24000000); //delay 1s
            __delay_cycles(120000000); //delay 5s
//        __delay_cycles(240000000); //delay 10s
//        __delay_cycles(1440000000); //delay 60s
        if(batteryVoltageCheck >= 3.8){
            __delay_cycles(120000000); //delay 5s
        }
        if(batteryVoltageCheck >= 3.85){
            __delay_cycles(240000000); //delay 10s
        }
        if(batteryVoltageCheck >= 3.95){
            __delay_cycles(240000000); //delay 10s
        //    __delay_cycles(240000000); //delay 10s
        //    __delay_cycles(240000000); //delay 10s
        }
        if(batteryVoltageCheck >= 4.05){
            __delay_cycles(1440000000); //delay 60s
        //    __delay_cycles(1440000000); //delay 60s
        }
        if(batteryVoltageCheck >= 4.19){
            __delay_cycles(1440000000); //delay 60s
            __delay_cycles(1440000000); //delay 60s
            __delay_cycles(1440000000); //delay 60s
            __delay_cycles(1440000000); //delay 60s
//            __delay_cycles(1440000000); //delay 60s
//            __delay_cycles(1440000000); //delay 60s
//            __delay_cycles(1440000000); //delay 60s
        }
        GPIO_setOutputHighOnPin(CASE_G1);      //通信モードに入ります
    }
}
/*
 * ======== TIMER1_A0_ISR ========
 */
#if defined(__TI_COMPILER_VERSION__) || (__IAR_SYSTEMS_ICC__)
#pragma vector=TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR (void)
#elif defined(__GNUC__) && (__MSP430__)
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) TIMER0_A0_ISR (void)
#else
#error Compiler not found! 
#endif
{
    // wake on CCR0 count match
    TA0CCTL0 = 0;
    __bic_SR_register_on_exit(LPM0_bits|GIE);
}
//  ======== UART RX Interrupt ========
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported! 
#endif
{
  switch(__even_in_range(UCA0IV,4))
  {
  case 0:break;                             // Vector 0 - no interrupt
  case 2:                                   // Vector 2 - RXIFG
      GPIO_toggleOutputOnPin(LED_5);
      RegValueMSB = UCA0RXBUF;              //受信バイトを RegValueMSB に割り当てます
      if (RegValueMSB == 0xD5){ //充電完了バイトを確認します
          StdI2C_P_TX_Single(BQ25619_ADDR,0x01 , 0x1A, &Err);//充電完了時に BQ25619 昇圧モードをディスエーブルにします
      }
      else{
      stobuf1 = RegValueMSB * 6;
      stobuf2 = (double)stobuf1 / 256;       //Vbat を計算します
      batteryVoltageCheck = stobuf2;
      if(batteryVoltageCheck <= 4.05){
          //PwmDuty = 40-((stobuf2-2.6)/.095);
          PwmDuty =((7.606829268 - (1.434146341*(stobuf2 + .33)))*(40/3.3)); //~= .3v headroom for longer intervals
      }
      // stobuf2  is holder for Vbat
      //PwmDuty の範囲は 0 = 0% = 5.3V から 40 = 100% = 3V です
      if (PwmDuty >= 14 && PwmDuty <= 40){ //PwmDuty を制限し、電圧を 4.5 を超えて上げないでください
          TA2CCR2 = PwmDuty; //PwmDuty サイクルを割り当てます
      }
      else{
      TA2CCR2 = 14;
      }
      __delay_cycles(40000);
      GPIO_setOutputLowOnPin(CASE_G1);      //パワー・モードに入ります
      }
    break;
  case 4:break;                             // Vector 4 - TXIFG
  default: break;
  }
}
//Released_Version_5_10_00_17