Hardware Used:

GPIO Overview:

GPIO (General Purpose Input Output) features on Bouffalo series chips include:

In BL MCU SDK, pin configuration can be done in two ways:

How does the PIR Sensor work?

Every object above absolute zero emits infrared radiation. Hotter objects emit more radiation, which is invisible to the human eye. PIR sensors are designed to detect this radiation.

Components:

Working Principle:

When motion is not detected, the output is zero (background radiation). When motion occurs in front of either half of the sensor, voltage changes between the two halves, indicating movement.

Fresnel Lens: Composed of concentric grooves acting as individual refracting surfaces to focus light, enhancing detection range and field of view.

HC-SR501 Wiring Diagram:

Three pins hidden under the Fresnel lens:

Trigger Modes:

Adjustments:

Voltage Regulator:

Onboard 3.3V regulator allows 4.5V–12V supply (5V preferred).

Troubleshooting:

Code Snippet Explanation:

#include "bflb_mtimer.h"

#include "board.h"

#include "bflb_gpio.h"

#include "locale.h"

#define DBG_TAG "MAIN"

#include "log.h"

 

struct bflb_device_s *gpio;

int main(void)

{

    board_init();

    gpio = bflb_device_get_by_name("gpio");

    bflb_gpio_init(gpio, GPIO_PIN_13, GPIO_INPUT | GPIO_PULLDOWN | GPIO_SMT_EN | GPIO_DRV_0);

    bflb_gpio_init(gpio, GPIO_PIN_12, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0);

    while (1) {

        bool isH = bflb_gpio_read(gpio, GPIO_PIN_13);

        if (isH) {

            bflb_gpio_set(gpio, GPIO_PIN_12);

        } else {

            bflb_gpio_reset(gpio, GPIO_PIN_12);

        }

        LOG_F("Motion detected=%d\r\n", isH);

        bflb_mtimer_delay_ms(500);

    }

}

Step 1:

Build project, connect Ai-M61-32S to HC-SR501 PIR module, and read state.

TTS Module: XFS5152CE Text-To-Speech

TTS (Text-To-Speech) converts text into speech. Options include:

XFS5152CE Features:

Since the protocol uses I2C, the I2C function is encapsulated for convenience.

Wire.h

#pragma once

 

// #include "bouffalo\_sdk.h"

#include "bflb\_gpio.h"

#include "bl616\_gpio.h"

#include "bl616\_glb.h"

#include "bl616\_glb\_gpio.h"

#include "../../drivers/lhal/include/hardware/i2c\_reg.h"

#include "bflb\_i2c.h"

#define lowByte(w) ((uint8\_t) ((w) & 0xff))

#define highByte(w) ((uint8\_t) ((w) >> 8))

 

bool getWireTimeoutFlag();

bool clearWireTimeoutFlag();

void setWireTimeout(int timeout, bool reset\_on\_timeout);

void onRequest(void (\*callback)());

void onReceive(void (\*callback)(int));

void setClock(int clockFrequency);

int readI2c();

int available();

int write\_len(uint8\_t \*str, int len);

int write\_str(uint8\_t \*str);

int write\_char(unsigned char value);

void endTransmission\_stop(bool stop);

void endTransmission();

void beginTransmission(unsigned char addr);

int requestFrom\_stop(unsigned char addr, int quantity, bool stop);

int requestFrom(unsigned char addr, int quantity);

void end();

void begin\_addr(unsigned char addr);

void begin();

Among them

#define lowByte(w) ((uint8_t) ((w) & 0xff))

#define highByte(w) ((uint8_t) ((w) >> 8))

is the method in Arduino, mainly to obtain high and low data.

Wire.c

#include "Wire.h"

 

#define PUT_UINT32_LE(field, value)            \

    do {                                       \

        (field)[0] = (uint8_t)((value) >> 0);  \

        (field)[1] = (uint8_t)((value) >> 8);  \

        (field)[2] = (uint8_t)((value) >> 16); \

        (field)[3] = (uint8_t)((value) >> 24); \

    } while (0)
struct bflb_device_s *i2c0;

uint8_t rbuf[128];

int available_count;

int indexi2c;

int wire_timeout;

bool wire_timeout_flag;

 

void board_i2c_pinmux_init(void)

{

    GLB_GPIO_Type pinlist[] = {

        GLB_GPIO_PIN_30,

        GLB_GPIO_PIN_31

    };

    GLB_GPIO_Func_Init(GPIO_FUN_I2C0, pinlist, 2);

}

 

bool bflb_i2c_isend(struct bflb_device_s *dev)

{

    uint32_t regval;

    uint32_t reg_base;

 

    reg_base = dev->reg_base;

 

    regval = getreg32(reg_base + I2C_INT_STS_OFFSET);

 

    if (regval & I2C_END_INT) {

        return true;

    }
  return false;

}

 

bool bflb_i2c_isnak(struct bflb_device_s *dev)

{

    uint32_t regval;

    uint32_t reg_base;

 

    reg_base = dev->reg_base;

 

    regval = getreg32(reg_base + I2C_INT_STS_OFFSET);

 

    if (regval & I2C_NAK_INT) {

        return true;

    }

 

    return false;

}

 

bool bflb_i2c_isbusy(struct bflb_device_s *dev)

{

    uint32_t regval;

    uint32_t reg_base;

 

    reg_base = dev->reg_base;

 

    regval = getreg32(reg_base + I2C_BUS_BUSY_OFFSET);

 

    if (regval & I2C_STS_I2C_BUS_BUSY) {

        return true;

    }

 

    return false;

}

 

void bflb_i2c_enable(struct bflb_device_s *dev)

{

    uint32_t regval;

    uint32_t reg_base;

 

    reg_base = dev->reg_base;

 

    regval = getreg32(reg_base + I2C_CONFIG_OFFSET);

    regval |= I2C_CR_I2C_M_EN;

    putreg32(regval, reg_base + I2C_CONFIG_OFFSET);

}
bool bflb_i2c_isenable(struct bflb_device_s *dev)

{

    uint32_t regval;

    uint32_t reg_base;

 

    reg_base = dev->reg_base;

 

    regval = getreg32(reg_base + I2C_CONFIG_OFFSET);

    if (regval & I2C_CR_I2C_M_EN) {

        return true;

    }

 

    return false;

}

 

void bflb_i2c_disable(struct bflb_device_s *dev)

{

    uint32_t regval;

    uint32_t reg_base;

 

    reg_base = dev->reg_base;

 

    regval = getreg32(reg_base + I2C_CONFIG_OFFSET);

    regval &= ~I2C_CR_I2C_M_EN;

    putreg32(regval, reg_base + I2C_CONFIG_OFFSET);

    /* Clear I2C fifo */

    regval = getreg32(reg_base + I2C_FIFO_CONFIG_0_OFFSET);

    regval |= I2C_TX_FIFO_CLR;

    regval |= I2C_RX_FIFO_CLR;

    putreg32(regval, reg_base + I2C_FIFO_CONFIG_0_OFFSET);

    /* Clear I2C interrupt status */

    regval = getreg32(reg_base + I2C_INT_STS_OFFSET);

    regval |= I2C_CR_I2C_END_CLR;

    regval |= I2C_CR_I2C_NAK_CLR;

    regval |= I2C_CR_I2C_ARB_CLR;

    putreg32(regval, reg_base + I2C_INT_STS_OFFSET);

}
void bflb_i2c_set_dir(struct bflb_device_s *dev, bool is_in)

{

    uint32_t regval;

    uint32_t reg_base;

 

    reg_base = dev->reg_base;

 

    regval = getreg32(reg_base + I2C_CONFIG_OFFSET);

 

    if (is_in) {

        regval |= I2C_CR_I2C_PKT_DIR;

    } else {

        regval &= ~I2C_CR_I2C_PKT_DIR;

    }

    putreg32(regval, reg_base + I2C_CONFIG_OFFSET);

}
int bflb_i2c_write_bytes(struct bflb_device_s *dev, uint8_t *data, uint32_t len, uint32_t timeout)

{

    uint32_t reg_base;

    uint32_t temp = 0;

    uint8_t *tmp_buf;

    uint64_t start_time;

 

    reg_base = dev->reg_base;

    tmp_buf = data;

    while (len >= 4) {

        for (uint8_t i = 0; i < 4; i++) {

            temp += (tmp_buf[i] << ((i % 4) * 8));

        }

        tmp_buf += 4;

        len -= 4;

        start_time = bflb_mtimer_get_time_ms();

        while ((getreg32(reg_base + I2C_FIFO_CONFIG_1_OFFSET) & I2C_TX_FIFO_CNT_MASK) == 0) {

            if ((bflb_mtimer_get_time_ms() - start_time) > timeout) {

                return -ETIMEDOUT;

            }

        }

        putreg32(temp, reg_base + I2C_FIFO_WDATA_OFFSET);

        if (!bflb_i2c_isenable(dev)) {

            bflb_i2c_enable(dev);

        }

        temp = 0;

    }

 

    if (len > 0) {

        for (uint8_t i = 0; i < len; i++) {

            temp += (tmp_buf[i] << ((i % 4) * 8));

        }

        start_time = bflb_mtimer_get_time_ms();

        while ((getreg32(reg_base + I2C_FIFO_CONFIG_1_OFFSET) & I2C_TX_FIFO_CNT_MASK) == 0) {

            if ((bflb_mtimer_get_time_ms() - start_time) > timeout) {

                return -ETIMEDOUT;

            }

        }

        putreg32(temp, reg_base + I2C_FIFO_WDATA_OFFSET);

        if (!bflb_i2c_isenable(dev)) {

            bflb_i2c_enable(dev);

        }

    }

 

    start_time = bflb_mtimer_get_time_ms();

    while (bflb_i2c_isbusy(dev) || !bflb_i2c_isend(dev) || bflb_i2c_isnak(dev)) {

        if ((bflb_mtimer_get_time_ms() - start_time) > timeout) {

            return -ETIMEDOUT;

        }

    }

    bflb_i2c_disable(dev);

 

    return 0;

}
/*

 * address: the 7-bit slave address (optional); if not specified, join the bus as a controller device.

 */

void begin_addr(unsigned char addr) {

    wire_timeout = 100;

    wire_timeout_flag = false;

    board_i2c_pinmux_init();

    i2c0 = bflb_device_get_by_name("i2c0");

    bflb_i2c_init(i2c0, 50000);

}

 

void begin() {

    wire_timeout = 100;

    wire_timeout_flag = false;

    board_i2c_pinmux_init();

    i2c0 = bflb_device_get_by_name("i2c0");

    bflb_i2c_init(i2c0, 50000);

}

 

void end() {

    bflb_i2c_deinit(i2c0);

}

/*

 * address: the 7-bit slave address of the device to request bytes from.

 *

 * quantity: the number of bytes to request.

 *

 * stop: true or false. true will send a stop message after the request, releasing the bus.

 * False will continually send a restart after the request, keeping the connection active.

 */

 

int requestFrom_stop(unsigned char addr, int quantity, bool stop) {

    indexi2c = 0;

    bflb_i2c_disable(i2c0);

    bflb_i2c_enable(i2c0);

    bflb_i2c_addr_config(i2c0, addr, 0, 0, false);

    bflb_i2c_set_datalen(i2c0,quantity);

    bflb_i2c_set_dir(i2c0, 1);

    bflb_i2c_read_bytes(i2c0, rbuf,quantity,wire_timeout);

    available_count = quantity;

    if(true == stop){

        bflb_i2c_disable(i2c0);

    }

    return 0;

}

 

int requestFrom(unsigned char addr, int quantity) {

    indexi2c = 0;

    bflb_i2c_disable(i2c0);

    bflb_i2c_enable(i2c0);

    bflb_i2c_addr_config(i2c0, addr, 0, 0, false);

    bflb_i2c_set_datalen(i2c0,quantity);

    bflb_i2c_set_dir(i2c0, 1);

    bflb_i2c_read_bytes(i2c0, rbuf,quantity,wire_timeout);

    available_count = quantity;

    return 0;

}

 

/*

 * address: the 7-bit address of the device to transmit to.

 */

void beginTransmission(unsigned char addr) {

    //bflb_i2c_enable(i2c0);

    bflb_i2c_addr_config(i2c0, addr, 0, 0, false);

    bflb_i2c_set_dir(i2c0, 0);

}

 

/*

 * stop: true or false. True will send a stop message, releasing the bus after transmission.

 * False will send a restart, keeping the connection active.

 *

 * Returns

 * 0: success.

 * 1: data too long to fit in transmit buffer.

 * 2: received NACK on transmit of address.

 * 3: received NACK on transmit of data.

 * 4: other error.

 * 5: timeout

 */

 

void endTransmission_stop(bool stop) {

    bflb_i2c_disable(i2c0);

}

 

void endTransmission() {

    bflb_i2c_disable(i2c0);

 

}

 

/*

 * Description

 * This function writes data from a peripheral device in response to a request from

 * a controller device, or queues bytes for transmission from a controller to

 * peripheral device (in-between calls to beginTransmission() and endTransmission()).

 * Syntax

 * Wire.write(value) Wire.write(string) Wire.write(data, length)

 * Parameters

 * value: a value to send as a single byte.

 * string: a string to send as a series of bytes.

 * data: an array of data to send as bytes.

 * length: the number of bytes to transmit.

 * Returns

 * The number of bytes written (reading this number is optional).

 */

int write_char(unsigned char value) {

    bflb_i2c_set_datalen(i2c0, 1);

    bflb_i2c_write_bytes(i2c0, &value, 1,wire_timeout);

  return 0;

}

int write_str(uint8_t *str) {

    bflb_i2c_set_datalen(i2c0, strlen((const char*)str));

    bflb_i2c_write_bytes(i2c0, str, strlen((const char*)str),wire_timeout);

  return 0;

}

int write_len(uint8_t *str, int len) {

    bflb_i2c_set_datalen(i2c0, len);

    int ret = bflb_i2c_write_bytes(i2c0, str, len,wire_timeout);

  return ret;

}

 

/*

 * Description

 * This function returns the number of bytes available for retrieval with read().

 * This function should be called on a controller device after a call to

 * requestFrom() or on a peripheral inside the onReceive() handler.

 * available() inherits from the Stream utility class.

 */

 

int available() {

    return available_count;

}

 

/*

 * Description

 * This function reads a byte that was transmitted from a peripheral device to

 * a controller device after a call to requestFrom() or was transmitted from a

 * controller device to a peripheral device. read() inherits from the Stream utility class.

 * Syntax

 * Wire.read()

 * Parameters

 * None.

 * Returns

 * The next byte received.

 */

 

int readI2c() {

    unsigned char ret;

    if(available_count){

        available_count--;

        ret = rbuf[indexi2c];

        indexi2c++;

        return ret;

    }

    return 0;

}

 

/*

 * Description

 * This function modifies the clock frequency for I2C communication.

 * I2C peripheral devices have no minimum working clock frequency,

 * however 100KHz is usually the baseline.

 * Syntax

 * Wire.setClock(clockFrequency)

 * Parameters

 * clockFrequency: the value (in Hertz) of the desired communication clock.

 * Accepted values are 100000 (standard mode) and 400000 (fast mode).

 * Some processors also support 10000 (low speed mode), 1000000 (fast mode plus)

 * and 3400000 (high speed mode). Please refer to the specific processor documentation

 * to make sure the desired mode is supported.

 * Returns

 * None.

 */

void setClock(int clockFrequency) {

    bflb_i2c_deinit(i2c0);

    bflb_i2c_init(i2c0, clockFrequency);

}

 

/*

 * Description

 * This function registers a function to be called when a peripheral device receives

 * a transmission from a controller device.

 * Syntax

 * Wire.onReceive(handler)

 * Parameters

 * handler: the function to be called when the peripheral device receives data;

 * this should take a single int parameter (the number of bytes read from the controller

 * device) and return nothing.

 * Returns

 * None.

 */

void onReceive(void (*callback)(int)) {

    //we not support slave mode yet

}

 

/*

 * Description

 * This function registers a function to be called when a controller device requests data from a peripheral device.

 * Syntax

 * Wire.onRequest(handler)

 * Parameters

 * handler: the function to be called, takes no parameters and returns nothing.

 * Returns

 * None.

 */

void onRequest(void (*callback)()) {

    //we not support slave mode yet

}

 

/*

 * Description

 * Sets the timeout for Wire transmissions in master mode.

 * Syntax

 * Wire.setWireTimeout(timeout, reset_on_timeout)

 * Wire.setWireTimeout()

 * Parameters

 * timeout a timeout: timeout in microseconds, if zero then timeout checking is disabled

 * reset_on_timeout: if true then Wire hardware will be automatically reset on timeout

 * When this function is called without parameters, a default timeout is configured that

 * should be sufficient to prevent lockups in a typical single-master configuration.

 * Returns

 * None.

 */

void setWireTimeout(int timeout, bool reset_on_timeout) {

    wire_timeout = timeout;

    wire_timeout_flag = true;

}

 

/* Description

 * Clears the timeout flag.

 * Timeouts might not be enabled by default. See the documentation for Wire.setWireTimeout()

 * for more information on how to configure timeouts and how they work.

 * Syntax

 * Wire.clearTimeout()

 * Parameters

 * None.

 * Returns

 * bool: The current value of the flag

 */

bool clearWireTimeoutFlag() {

    wire_timeout_flag = false;

  return true;

}

 

/*

 * Description

 * Checks whether a timeout has occured since the last time the flag was cleared.

 * This flag is set is set whenever a timeout occurs and cleared when Wire.clearWireTimeoutFlag()

 * is called, or when the timeout is changed using Wire.setWireTimeout().

 * Syntax

 * Wire.getWireTimeoutFlag()

 * Parameters

 * None.

 * Returns

 * bool: The current value of the flag

 */

 

bool getWireTimeoutFlag() {

  return wire_timeout_flag;

}

The I2C pins are modified here;

GLB_GPIO_Type pinlist[] = {

GLB_GPIO_Type pinlist[] = {

GLB_GPIO_PIN_30,

GLB_GPIO_PIN_31

};

The default is GLB_GPIO_PIN_14, GLB_GPIO_PIN_15.

Then encapsulate, XFS5152CE module function code;

XFS.h

#ifndef __XFS_H

#define __XFS_H

 

#include <stdlib.h>

#include <stdbool.h>

#include <stdarg.h>

#include <stddef.h>

#include <string.h>

#include <math.h>

#include <stdint.h> //Added for uint_t

#include <stdio.h>

#include "bflb_mtimer.h"

 

struct XFS_Protocol_TypeDef

{

uint8_t DataHead;

uint8_t Length_HH;

uint8_t Length_LL;

uint8_t Commond;

uint8_t EncodingFormat;

const char* Text;

};

 

/*

*| Frame header (1Byte)| Data area length (2Byte)| Data area (<4KByte) |

*| | High byte | Low byte | Command word | Text encoding format | Text to be synthesized |

*| 0xFD | 0xHH | 0xLL | 0x01 | 0x00~0x03 | ... ... |

*/

 

typedef enum

{

CMD_StartSynthesis = 0x01, // Voice synthesis command

CMD_StopSynthesis = 0x02, // Stop synthesis command, no parameters

CMD_PauseSynthesis = 0x03, // Pause synthesis command, no parameters

CMD_RecoverySynthesis = 0x04, // Resume synthesis command, no parameters

CMD_CheckChipStatus = 0x21, // Chip status query command

CMD_PowerSavingMode = 0x88, // Chip enters power saving mode

CMD_NormalMode = 0xFF // Chip returns to normal working mode from power saving mode

} CMD_Type; // Command word

void StartSynthesis(const char* str);//Start synthesis

// void StartSynthesis(String str);//Start synthesis

 

bool IIC_WriteByte(uint8_t data);

void IIC_WriteByteSize(uint8_t* buff, uint32_t size);

void SendCommond(CMD_Type cmd);

void StopSynthesis();//Stop synthesis

void PauseSynthesis();//Pause synthesis

void RecoverySynthesis();//Resume synthesis

 

typedef enum

{

GB2312 = 0x00,

GBK = 0x01,

BIG5 = 0x02,

UNICODE = 0x03

} EncodingFormat_Type;//Text encoding format

void SetEncodingFormat(EncodingFormat_Type encodingFormat);

 

typedef enum

{

ChipStatus_InitSuccessful = 0x4A, //Successful initialization feedback

ChipStatus_CorrectCommand = 0x41, //Correct command frame received feedback

ChipStatus_ErrorCommand = 0x45, //Unrecognizable command frame received feedback

ChipStatus_Busy = 0x4E, //Chip busy status feedback

ChipStatus_Idle = 0x4F //Chip idle status feedback

} ChipStatus_Type; //Chip feedback

 

typedef enum

{

Style_Single, //? 0, one word per pause style

Style_Continue //? =1, normal synthesis

} Style_Type; //Synthesis style setting [f?]

void SetStyle(Style_Type style);

 

typedef enum

{

Language_Auto,//? 0, automatic language judgment

Language_Chinese,//? 1, Arabic numerals, units of measurement, special symbols, etc. are synthesized into Chinese

Language_English//? 2, Arabic numerals, units of measurement, special symbols, etc. are synthesized into English

} Language_Type; //Synthesis language setting [g?]

void SetLanguage(Language_Type language);

 

typedef enum

{

Articulation_Auto,//? 0, automatic word pronunciation

Articulation_Letter,//? 1, letter pronunciation

Articulation_Word//? 2, word pronunciation

} Articulation_Type; //Set word pronunciation [h?]

void SetArticulation(Articulation_Type articulation);

 

typedef enum

{

Spell_Disable, //? is 0, do not recognize Chinese Pinyin

Spell_Enable //? is 1, recognize "Pinyin + 1 digit (tone)" as Chinese Pinyin, for example: hao3

} Spell_Type; //Set the recognition of Chinese Pinyin [i?]

void SetSpell(Spell_Type spell);

 

typedef enum

{

Reader_XiaoYan = 3, //? is 3, set the pronunciation person to Xiaoyan (female voice, recommended pronunciation person)

Reader_XuJiu = 51, //? is 51, set the pronunciation person to Xujiu (male voice, recommended pronunciation person)

Reader_XuDuo = 52, //? is 52, set the pronunciation person to Duoyi (male voice)

Reader_XiaoPing = 53, //? is 53, set the pronunciation person to Xiaoping (female voice)

Reader_DonaldDuck = 54,//? is 54, set the speaker to Donald Duck (effector)

Reader_XuXiaoBao = 55//? is 55, set the speaker to Xu Xiaobao (female voice)

} Reader_Type;//Select the speaker [m?]

void SetReader(Reader_Type reader);

 

typedef enum

{

NumberHandle_Auto,//? is 0, automatic judgment

NumberHandle_Number,//? is 1, the number is processed as a number

NumberHandle_Value//? is 2, the number is processed as a value

} NumberHandle_Type; //Set the number processing strategy [n?]

void SetNumberHandle(NumberHandle_Type numberHandle);

 

typedef enum

{

ZeroPronunciation_Zero,//? is 0, read as "zero

ZeroPronunciation_O//? is 1, pronounced as "Ou"

} ZeroPronunciation_Type; //The pronunciation of the number "0" when reading English or numbers [o?]

void SetZeroPronunciation(ZeroPronunciation_Type zeroPronunciation);

 

typedef enum

{

NamePronunciation_Auto,//? is 0, automatically determine the surname pronunciation

NamePronunciation_Constraint//? is 1, force the surname pronunciation rule to be used

} NamePronunciation_Type; //Set the name pronunciation strategy [r?]

void SetNamePronunciation(NamePronunciation_Type namePronunciation);

 

void SetSpeed(int speed);//Set the speech speed [s?] ? is the speech speed value, value: 0~10

void SetIntonation(int intonation);//Set the intonation [t?] ? is the intonation value, value: 0~10

void SetVolume(int volume);//Set volume [v?] ? is the volume value, value: 0~10

 

typedef enum

{

PromptTone_Disable,//? is 0, do not use prompt tone

PromptTone_Enable//? is 1, use prompt tone

} PromptTone_Type; //Set prompt tone processing strategy [x?]

void SetPromptTone(PromptTone_Type promptTone);

 

typedef enum

{

OnePronunciation_Yao,//? is 0, the composite number "1" is read as "yao"

OnePronunciation_Yi//? is 1, the composite number "1" is read as "yi"

} OnePronunciation_Type; //Set the pronunciation of "1" in the number [y?]

void SetOnePronunciation(OnePronunciation_Type onePronunciation);

 

typedef enum

{

Rhythm_Diasble, //? is 0, "*" and "#" read out symbols

Rhythm_Enable //? is 1, processed into rhythm, "*" is used for word breaks, "#" is used for pauses

} Rhythm_Type; //Whether to use rhythm marks "*" and "#" [z?]

void SetRhythm(Rhythm_Type rhythm);

 

void SetRestoreDefault();//Restore default synthesis parameters [d] All settings (except speaker settings and language settings) are restored to default values

 

void XFS5152CE(uint8_t encodingFormat);

void Begin(uint8_t addr);

uint8_t GetChipStatus();

void TextCtrl(char c, int d);

 

#endif

XFS.c

#include "XFS.h"

#include <Wire.h>

#define DBG_TAG "MAIN"

#include "log.h"

 

#define XFS_DataHead (uint8_t)0xFD

 

uint8_t I2C_Addr;

uint8_t ChipStatus;

struct XFS_Protocol_TypeDef DataPack;

 

size_t foo( const char* restrict src, uint8_t* restrict dst, size_t dst_maxlen )

{

size_t idx = 0;

for( ; src[idx] && dst_maxlen; ++idx )

{

if(idx%8 == 0)

*dst = 0;

if( src[idx] != '0' )

*dst |= 1<<(7-idx%8);

if( idx%8 == 7 )

++dst, --dst_maxlen;

}

return (idx+7)/8;

}

 

void XFS5152CE(uint8_t encodingFormat)

{

DataPack.DataHead = XFS_DataHead;

DataPack.Length_HH = 0x00;

DataPack.Length_LL = 0x00;

 

DataPack.Commond = 0x00;

DataPack.EncodingFormat = encodingFormat;

 

ChipStatus = 0x00;

}

 

 

void Begin(uint8_t addr)

{

I2C_Addr = addr;

XFS5152CE(GB2312);

begin();

}

 

uint8_t GetChipStatus()

{

uint8_t AskState[4] = {0xFD,0x00,0x01,0x21};

beginTransmission(I2C_Addr);

write_len(AskState,4);

endTransmission();

bflb_mtimer_delay_ms(100);

requestFrom(I2C_Addr, 1);

while (available())

{

ChipStatus = readI2c();

}

 

LOG_F("ChipStatus=%x\r\n", ChipStatus);

return ChipStatus;

}

 

 

bool IIC_WriteByte(uint8_t data)

{

beginTransmission(I2C_Addr);

write_char(data);

endTransmission();

// if(endTransmission()!=0) //Send end signal

// {

// bflb_mtimer_delay_ms(10);

// return false;

// } bflb_mtimer_delay_ms(10);

return true;

}

 

void IIC_WriteBytes(uint8_t* buff, uint32_t size)

{

for (uint32_t i = 0; i < size; i++)

{

IIC_WriteByte(buff[i]);

}

}

 

void StartSynthesis(const char* str)

{

uint16_t size = strlen(str) + 2;

DataPack.Length_HH = highByte(size);

DataPack.Length_LL = lowByte(size);

DataPack.Commond = CMD_StartSynthesis;

DataPack.Text = str;

 

uint8_t dst[(strlen(DataPack.Text)-1+7)/8];

size_t len = foo(DataPack.Text, dst, sizeof(dst)/sizeof(*dst) );

IIC_WriteBytes((uint8_t*)&DataPack,5);

IIC_WriteBytes(DataPack.Text, strlen(str));

 

}