first commit v2.0.1

This commit is contained in:
hulk
2024-08-08 19:18:16 +08:00
commit f526aa2b8f
159 changed files with 43838 additions and 0 deletions

194
CHIRP/board/app_config.h Normal file
View File

@@ -0,0 +1,194 @@
/*
* _____________________________________________________________________________
* Copyright (c) 2020-2021 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto
* (collectively "Software") is subject to InvenSense and its licensors'
* intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary
* rights in and to the Software and any use, reproduction, disclosure or
* distribution of the Software without an express license agreement from
* InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE
* SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. EXCEPT AS OTHERWISE
* PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* _____________________________________________________________________________
*/
/*! \file app_config.h */
#ifndef APP_CONFIG_H
#define APP_CONFIG_H
#include "soniclib.h"
/*========================= Sensor Firmware Selection ===========================*/
/* Select sensor firmware to use
* The sensor firmware type is specified during the call to ch_init(), by
* giving the name (address) of the firmware initialization function that will
* be called. The CHIRP_SENSOR_FW_INIT_FUNC symbol is used to specify the
* init routine for the sensor firmware to be used.
*
* Uncomment ONE of the following lines to use that sensor firmware type.
* You must choose a firmware type that is appropriate for the sensor model
* you are using (CH101 or CH201).
*
* To use a different sensor firmware type than those listed here (for
* example, a new distribution from Chirp), simply define
* CHIRP_SENSOR_FW_INIT_FUNC to equal the name of the init routine for
* the new firmware.
*
* Short Range Firmware:
* CH101 sensor firmware with "sr" in the name, e.g. ch101_gpr_sr, is
* optimized for short range. The short range firmware has 4 times the
* resolution, but only 1/4 the maximum range. If you use this option, you
* should redefine the CHIRP_SENSOR_MAX_RANGE_MM symbol, below, to 250mm or
* less.
*/
/* CH101 GPR - general purpose rangefinding, standard range */
#define CHIRP_SENSOR_FW_INIT_FUNC ch101_gpr_init
/* CH101 GPR NARROW - general purpose rangefinding, narrow FoV */
// #define CHIRP_SENSOR_FW_INIT_FUNC ch101_gpr_narrow_init
/* CH101 GPR SR - general purpose rangefinding, short range */
// #define CHIRP_SENSOR_FW_INIT_FUNC ch101_gpr_sr_init
/* CH101 GPR SR NARROW - general purpose rangefinding, short range, narrow FoV */
// #define CHIRP_SENSOR_FW_INIT_FUNC ch101_gpr_sr_narrow_init
/* CH201 GPRMT - general purpose rangefinding / multi threshold */
// #define CHIRP_SENSOR_FW_INIT_FUNC ch201_gprmt_init
/*=========================== Sensor Configuration ===========================*/
/* Maximum detection range for the sensor
* This value will determine how long the sensor "listens" for an ultrasound
* signal. Note that the maximum possible range will vary depending on sensor
* model (CH101 vs. CH201) and sensor firmware type. If the value specified
* here is greater than the maximum possible range, the maximum possible range
* will be used.
*/
#define CHIRP_SENSOR_MAX_RANGE_MM (750) /* maximum range, in mm */
/* Static target rejection range
* This value specifies if static target rejection (STR) will be used. If
* CHIRP_SENSOR_STATIC_RANGE is non-zero, STR will be enabled and will apply
* to the specified number of samples at the beginning of a measurement.
*/
#define CHIRP_SENSOR_STATIC_RANGE (100) /* static target rejection sample
range, in samples (0=disabled) */
/*============================ Application Timing ============================*/
/* Define how often the application will get a new sample from the sensor(s)
* This macro defines the sensor measurement interval, in milliseconds.
*
* For sensors in triggered mode (CH_MODE_TRIGGERED_TX_RX or
* CH_MODE_TRIGGERED_RX_ONLY), the application will use a periodic timer to
* trigger a sensor measurement each time this period elapses.
*
* For sensors in free-running mode (CH_MODE_FREERUN), the application will
* set this period as the sensor's internal sample interval.
*/
#define MEASUREMENT_INTERVAL_MS (200)
/*================== Application Storage for Sensor Data ====================*/
/* Define how many samples per measurement are expected by this application
* The following macro is used to allocate array storage in the "chirp_data_t"
* structure, defined in main.c. That structure contains arrays for
* individual data values (I/Q or amplitude) that describe the raw samples
* within an ultrasound measurement.
*
* Because a Chirp CH201 sensor has more samples in each measurement than a
* CH101 device, the CH201 sample count is used here by default. If you are
* ONLY using CH101 devices with this application, you may redefine the
* following symbol to CH101_MAX_NUM_SAMPLES to use less memory.
*/
#define DATA_MAX_NUM_SAMPLES CH101_MAX_NUM_SAMPLES // use CH101 only
/*=============== Build Options for Amplitude Data Handling =================*/
/* The following build options control if and how the full amplitude data for
* all internal samples within an ultrasound measurement will be read and
* displayed. This data is separate from the standard range and simple target
* amplitude values that are normally output.
*
* Note that reading the full amplitude data is not required for most basic
* sensing applications - the reported range value, possibly combined with the
* simple target amplitude value, is typically all that is required. However,
* the full set of amplitude values may be read and analyzed for more advanced
* sensing or data capture needs.
*
* Comment or un-comment the various definitions, as appropriate.
*
* Define READ_AMPLITUDE_DATA to enable readout of the amplitude data.
* Define OUTPUT_AMPLITUDE_DATA to enable output of the amplitude data via the
* serial port, as ascii values, one per line.
*/
// #define READ_AMPLITUDE_DATA /* uncomment to readout amplitude data */
// #define OUTPUT_AMPLITUDE_DATA /* uncomment to output data in ascii */
/*================== Build Options for I/Q Data Handling ====================*/
/* The following build options control if and how the raw I/Q data is read
* from the device after each measurement cycle, in addition to the standard
* range and amplitude.
*
* Note that reading the I/Q data is not required for most basic sensing
* applications - the reported range value is typically all that is required.
* However, the full data set may be read and analyzed for more advanced
* sensing or data capture needs.
*
* Comment or un-comment the various definitions, as appropriate.
*
* Define READ_IQ_DATA to enable readout of the I/Q data.
*
* By default, this application will read the I/Q data in blocking mode
* (i.e. READ_IQ_BLOCKING is defined by default). The data will be read from
* the device and placed in the I/Q data array field in the application's
* chirp_data structure. Because the I/Q data is read in blocking mode, the
* call to ch_get_iq_data() will not return until the data has actually
* been copied from the device.
*
* If, however, READ_IQ_NONBLOCKING is defined instead, the I/Q data will be
* read in non-blocking mode. The ch_get_iq_data() call will return immediately,
* and a separate callback function will be called to notify the application
* when the read operation is complete.
*
* Finally, if OUTPUT_IQ_DATA_CSV is defined, the application will write the
* I/Q data values out through the serial port in ascii form as comma-separated
* numeric value pairs (Q,I). This can make it easier to take the data
* from the application and analyze it in a spreadsheet or other program.
*/
// #define READ_IQ_DATA /* uncomment this line to readout I/Q data */
// #define READ_IQ_BLOCKING /* use blocking mode when reading I/Q */
// #define READ_IQ_NONBLOCKING /* use non-blocking mode when reading I/Q */
// #define OUTPUT_IQ_DATA_CSV /* uncomment to output I/Q data in CSV format */
#endif /* APP_CONFIG_H */

32
CHIRP/board/app_version.h Normal file
View File

@@ -0,0 +1,32 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2020-2021 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively “Software”) is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
/*! \file app_version.h */
#ifndef APP_VERSION_H
#define APP_VERSION_H
#define APP_VERSION_MAJOR 2
#define APP_VERSION_MINOR 0
#define APP_VERSION_REV 1
#endif /* APP_VERSION_H */

View File

@@ -0,0 +1,49 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <stdint.h>
#include "gd32e23x.h"
#include "systick.h"
#include "chirp_smartsonic.h"
#include "soniclib.h"
#include "chirp_bsp.h"
#include "board_init.h"
#include "chirp_board_config.h"
#include "app_config.h"
void sensor_led_on(void) {
gpio_bit_reset(CHIRP_PIN_LED_PORT, CHIRP_PIN_LED_PIN); // PB1 = Lo LED = On
}
void sensor_led_off(void) {
gpio_bit_set(CHIRP_PIN_LED_PORT, CHIRP_PIN_LED_PIN); // PB1 = Hi LED = Off
}
void sensor_led_toggle(void)
{
gpio_bit_toggle(CHIRP_PIN_LED_PORT, CHIRP_PIN_LED_PIN);
}
/*!
\brief Indicate Board Alive
\param[in] none
\param[out] none
\retval none
\note LED Heart Beat
*/
void indicate_alive(void){
gpio_bit_reset(CHIRP_PIN_LED_PORT, CHIRP_PIN_LED_PIN); // PB1 = Lo LED = On
delay_ms(100);
gpio_bit_set(CHIRP_PIN_LED_PORT, CHIRP_PIN_LED_PIN); // PB1 = Hi LED = Off
delay_ms(100);
gpio_bit_reset(CHIRP_PIN_LED_PORT, CHIRP_PIN_LED_PIN); // PB1 = Lo LED = On
delay_ms(100);
gpio_bit_set(CHIRP_PIN_LED_PORT, CHIRP_PIN_LED_PIN); // PB1 = Hi LED = Off
delay_ms(300);
}

View File

@@ -0,0 +1,781 @@
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "gd32e23x.h"
#include "systick.h"
#include "soniclib.h"
#include "chirp_smartsonic.h"
#include "board_init.h"
#include "chirp_board_config.h"
#include "i2c.h"
static uint8_t chirp_i2c_addrs[] = CHIRP_I2C_ADDRS;
static uint8_t chirp_i2c_buses[] = CHIRP_I2C_BUSES;
/* chirp sensor group pointer */
ch_group_t *sensor_group_ptr;
/* Callback function pointers */
static ch_timer_callback_t periodic_timer_callback_ptr = NULL;
static uint16_t periodic_timer_interval_ms;
static uint16_t ultrasound_timer_period_in_tick = 0xFFFF;
static uint16_t ultrasound_prev_period_end_in_tick;
/* Counter used to decimate call to ultrasound timer callback from TC0 ISR in case decimation
factor is != 1 */
static uint8_t decimation_counter = 0;
#ifdef CHIRP_ADC_NONE
static void measure_idd(uint16_t nb_measure){
__NOP();
}
#elif
static void measure_idd(uint16_t nb_measure){
}
#endif
#ifdef CHIRP_ADC_NONE
static void measure_power(void){
__NOP();
}
#elif
static void measure_power(void){
uint32_t sensors_current;
sensors_current = measure_idd(SENSORS_CURRENT_NB_MEASURE);
printf("Chirp Sensor Idd is %ld uA \n\n", sensors_current);
}
#endif
/*!
\brief Probe I2C bus to find connected sensor(s)
\param[in] none
\param[out] none
\retval none
\note 1. Pull-High PROG
2. Read Register From PROG Mode 0x00
3. Verify Register Value.
4. Pull-Low PROG
*/
static void find_sensors(void)
{
uint8_t sig_bytes[2];
uint8_t i;
/* config RST GPIO : --Output--High-- */
gpio_mode_set(CHIRP_PIN_RST_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, CHIRP_PIN_RST_PIN);
gpio_output_options_set(CHIRP_PIN_RST_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, CHIRP_PIN_RST_PIN);
gpio_bit_set(CHIRP_PIN_RST_PORT, CHIRP_PIN_RST_PIN);
/* config PROG GPIO : --Output--Low-- */
gpio_mode_set(CHIRP_PIN_PROG_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, CHIRP_PIN_PROG_PIN);
gpio_output_options_set(CHIRP_PIN_PROG_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, CHIRP_PIN_PROG_PIN);
gpio_bit_reset(CHIRP_PIN_PROG_PORT, CHIRP_PIN_PROG_PIN);
/* check sensor */
/* pull PROG Pin to high */
gpio_bit_set(CHIRP_PIN_PROG_PORT, CHIRP_PIN_PROG_PIN);
i2c_master_initialize1();
sig_bytes[0] = 0;
sig_bytes[1] = 0;
i2c_master_read_register1(CH_I2C_ADDR_PROG, 0x00, 2, sig_bytes);
printf("Chirp Sensor ");
if ((sig_bytes[0] = CH_SIG_BYTE_0) && (sig_bytes[1] = CH_SIG_BYTE_1)){
printf("found!\n");
} else {
printf("not found!\n");
}
gpio_bit_reset(CHIRP_PIN_PROG_PORT, CHIRP_PIN_PROG_PIN);
}
#ifdef CHIRP_ADC_NONE
static void ADC0_init(void){
__NOP();
}
#elif
static void ADC0_init(void){
adc_enable();
}
#endif
/*!
\brief Initialize INT Pin EXTI
\param[in] none
\param[out] none
\retval none
*/
void ext_int_init(void)
{
/* enable clock */
rcu_periph_clock_enable(RCU_GPIOA | RCU_CFGCMP);
// Configure PIOs as input pins & Enable pull-downs on the INT pins
gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO_PIN_7);
/* enable and set INT EXTI interrupt priority */
nvic_irq_enable(EXTI4_15_IRQn, 2U);
/* connect key EXTI line to key GPIO pin */
syscfg_exti_line_config(EXTI_SOURCE_GPIOA, EXTI_SOURCE_PIN7);
/* configure key EXTI line Initialize INT interrupt handler, interrupt on rising edge. */
exti_init(EXTI_7, EXTI_INTERRUPT, EXTI_TRIG_RISING);
exti_interrupt_flag_clear(EXTI_7);
/* Disable all CHx01 interrupts */
exti_interrupt_disable(EXTI_7);
}
/*!
\brief Initialize board HardWare
\param[in] none
\param[out] none
\retval none
\note This function performs all neceassary initialization on the board.
*/
void chbsp_board_init(ch_group_t *grp_ptr) {
/* make local copy of group pointer */
sensor_group_ptr = grp_ptr;
/* Initialize group descriptor */
grp_ptr->num_ports = CHIRP_MAX_NUM_SENSORS;
grp_ptr->num_i2c_buses = CHIRP_NUM_I2C_BUSES;
grp_ptr->rtc_cal_pulse_ms = CHBSP_RTC_CAL_PULSE_MS;
/* Initialize the GD32 system. */
// systick_config();
board_init_I2C();
configure_console();
ADC0_init();
ext_int_init();
/* Probe I2C bus to find connected sensor(s) */
find_sensors();
measure_power();
indicate_alive();
}
/*!
* \brief Assert the reset pin
*
* This function drives the sensor reset pin low.
*/
void chbsp_reset_assert(void) {
gpio_bit_reset(CHIRP_PIN_RST_PORT, CHIRP_PIN_RST_PIN); //reset=L
}
/*!
* \brief Deassert the reset pin
*
* This function drives the sensor reset pin high.
*/
void chbsp_reset_release(void) {
gpio_bit_set(CHIRP_PIN_RST_PORT, CHIRP_PIN_RST_PIN); //reset=H
}
/*!
* \brief Assert the PROG pin
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
*
* This function drives the sensor PROG pin high on the specified port.
*/
void chbsp_program_enable(ch_dev_t *dev_ptr) {
uint8_t dev_num = ch_get_dev_num(dev_ptr);
gpio_bit_set(CHIRP_PIN_PROG_PORT, CHIRP_PIN_PROG_PIN); //PROG_0=H
}
/*!
* \brief Deassert the PROG pin
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
*
* This function drives the sensor PROG pin low on the specified port.
*/
void chbsp_program_disable(ch_dev_t *dev_ptr) {
uint8_t dev_num = ch_get_dev_num(dev_ptr);
gpio_bit_reset(CHIRP_PIN_PROG_PORT, CHIRP_PIN_PROG_PIN); //PROG_0=L
}
/*!
* \brief Configure the Chirp sensor INT pin as an output for one sensor.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
*
* This function configures the Chirp sensor INT pin as an output (from the perspective
* of the host system).
*/
void chbsp_set_io_dir_out(ch_dev_t *dev_ptr) {
uint8_t dev_num = ch_get_dev_num(dev_ptr);
gpio_mode_set(CHIRP_PIN_INT_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, CHIRP_PIN_INT_PIN);
gpio_output_options_set(CHIRP_PIN_INT_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, CHIRP_PIN_INT_PIN);
}
/*!
* \brief Configure the Chirp sensor INT pin as an input for one sensor.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
*
* This function configures the Chirp sensor INT pin as an input (from the perspective of
* the host system).
*/
void chbsp_set_io_dir_in(ch_dev_t *dev_ptr) {
uint8_t dev_num = ch_get_dev_num(dev_ptr);
gpio_mode_set(CHIRP_PIN_INT_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, CHIRP_PIN_INT_PIN);
}
/*!
* \brief Configure the Chirp sensor INT pins as outputs for a group of sensors
*
* \param grp_ptr pointer to the ch_group_t config structure for a group of sensors
*
* This function configures each Chirp sensor's INT pin as an output (from the perspective
* of the host system).
*/
void chbsp_group_set_io_dir_out(ch_group_t *grp_ptr) {
uint8_t dev_num;
for (dev_num = 0; dev_num < ch_get_num_ports(grp_ptr); dev_num++)
{
ch_dev_t *dev_ptr = ch_get_dev_ptr(grp_ptr, dev_num);
if (ch_sensor_is_connected(dev_ptr)){
gpio_mode_set(CHIRP_PIN_INT_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, CHIRP_PIN_INT_PIN);
gpio_output_options_set(CHIRP_PIN_INT_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, CHIRP_PIN_INT_PIN);
}
}
}
/*!
* \brief Configure the Chirp sensor INT pins as inputs for a group of sensors
*
* \param grp_ptr pointer to the ch_group_t config structure for a group of sensors
*
* \note This function assumes a bidirectional level shifter is interfacing the ICs.
*/
void chbsp_group_set_io_dir_in(ch_group_t *grp_ptr) {
uint8_t dev_num;
for (dev_num = 0; dev_num < ch_get_num_ports(grp_ptr); dev_num++) {
ch_dev_t *dev_ptr = ch_get_dev_ptr(grp_ptr, dev_num);
if (ch_sensor_is_connected(dev_ptr)) {
gpio_mode_set(CHIRP_PIN_INT_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, CHIRP_PIN_INT_PIN);
}
}
}
/*!
* \brief Initialize the I/O pins.
*
* \param grp_ptr pointer to the ch_group_t config structure for a group of sensors
*
* Configure reset and program pins as outputs. Assert reset and program. Configure
* sensor INT pin as input.
*/
void chbsp_group_pin_init(ch_group_t *grp_ptr) {
uint8_t dev_num;
uint8_t port_num;
gpio_mode_set(CHIRP_PIN_PROG_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, CHIRP_PIN_PROG_PIN);
gpio_output_options_set(CHIRP_PIN_PROG_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, CHIRP_PIN_PROG_PIN);
gpio_bit_reset(CHIRP_PIN_PROG_PORT, CHIRP_PIN_PROG_PIN);
// ioport_set_pin_dir(CHIRP_RST, IOPORT_DIR_OUTPUT); //reset=output
gpio_mode_set(CHIRP_PIN_RST_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, CHIRP_PIN_RST_PIN);
gpio_output_options_set(CHIRP_PIN_RST_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, CHIRP_PIN_RST_PIN);
chbsp_reset_assert();
for (dev_num = 0; dev_num < grp_ptr->num_ports; dev_num++) {
ch_dev_t *dev_ptr = ch_get_dev_ptr(grp_ptr, dev_num);
chbsp_program_enable(dev_ptr);
}
/* Initialize IO pins */
chbsp_group_set_io_dir_in(grp_ptr);
/* Enable the peripheral clock for the MAG extension board interrupt pin. */
rcu_periph_clock_enable(CHIRP_PIN_INT_CLK);
rcu_periph_clock_enable(RCU_CFGCMP);
/* Configure PIOs as input pins. */
for(port_num = 0; port_num < grp_ptr->num_ports; port_num++ ) {
gpio_mode_set(CHIRP_PIN_INT_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, CHIRP_PIN_INT_PIN);
}
nvic_irq_enable(EXTI4_15_IRQn, 2U);
syscfg_exti_line_config(CHIRP_EXTI_INT_PORT, CHIRP_EXTI_INT_PIN);
exti_init(CHIRP_EXTI_INT_LINE, EXTI_INTERRUPT, EXTI_TRIG_RISING);
exti_interrupt_flag_clear(CHIRP_EXTI_INT_LINE);
}
/*!
* \brief Set the INT pins low for a group of sensors.
*
* \param grp_ptr pointer to the ch_group_t config structure for a group of sensors
*
* This function drives the INT line low for each sensor in the group.
*/
void chbsp_group_io_clear(ch_group_t *grp_ptr) {
// ioport_port_mask_t mask = 0;
uint8_t dev_num;
for (dev_num = 0; dev_num < ch_get_num_ports(grp_ptr); dev_num++) {
ch_dev_t *dev_ptr = ch_get_dev_ptr(grp_ptr, dev_num);
if (ch_sensor_is_connected(dev_ptr)) {
gpio_bit_reset(CHIRP_PIN_INT_PORT, CHIRP_PIN_INT_PIN); //INT_0=L
}
}
}
/*!
* \brief Set the INT pins high for a group of sensors.
*
* \param grp_ptr pointer to the ch_group_t config structure for a group of sensors
*
* This function drives the INT line high for each sensor in the group.
*/
void chbsp_group_io_set(ch_group_t *grp_ptr) {
ch_dev_t *dev_ptr = ch_get_dev_ptr(grp_ptr, 0);
if (ch_sensor_is_connected(dev_ptr))
{
gpio_bit_set(CHIRP_PIN_INT_PORT, CHIRP_PIN_INT_PIN);
}
}
/*!
* \brief Delay for specified number of microseconds
*
* \param us number of microseconds to delay before returning
*
* This function waits for the specified number of microseconds before returning to
* the caller.
*/
void chbsp_delay_us(uint32_t us) {
delay_us(us);
}
/*!
* \brief Delay for specified number of milliseconds.
*
* \param ms number of milliseconds to delay before returning
*
* This function waits for the specified number of milliseconds before returning to
* the caller.
*/
void chbsp_delay_ms(uint32_t ms) {
delay_ms(ms);
}
/*!
* \brief Initialize the host's I2C hardware.
*
* \return 0 if successful, 1 on error
*
* This function performs general I2C initialization on the host system.
*/
int chbsp_i2c_init(void) {
i2c_master_init();
return 0;
}
/*!
* \brief Return I2C information for a sensor port on the board.
*
* \param grp_ptr pointer to the ch_group_t config structure for a group of sensors
* \param dev_num device number within sensor group
* \param info_ptr pointer to structure to be filled with I2C config values
*
* \return 0 if successful, 1 if error
*
* This function returns I2C values in the ch_i2c_info_t structure specified by \a info_ptr.
* The structure includes three fields.
* - The \a address field contains the I2C address for the sensor.
* - The \a bus_num field contains the I2C bus number (index).
* - The \a drv_flags field contains various bit flags through which the BSP can inform
* SonicLib driver functions to perform specific actions during I2C I/O operations.
*/
uint8_t chbsp_i2c_get_info(ch_group_t __attribute__((unused)) *grp_ptr, uint8_t io_index, ch_i2c_info_t *info_ptr) {
uint8_t ret_val = 1;
if (io_index <= CHBSP_MAX_DEVICES) {
// info_ptr->address = chirp_i2c_addrs[io_index];
// info_ptr->bus_num = chirp_i2c_buses[io_index];
info_ptr->address = chirp_i2c_addrs[io_index];
info_ptr->bus_num = chirp_i2c_buses[io_index];
info_ptr->drv_flags = 0; // no special I2C handling by SonicLib driver is needed
ret_val = 0;
}
return ret_val;
}
/*!
* \brief Write bytes to an I2C slave.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
* \param data data to be transmitted
* \param num_bytes length of data to be transmitted
*
* \return 0 if successful, 1 on error or NACK
*
* This function writes one or more bytes of data to an I2C slave device.
* The I2C interface must have already been initialized using \a chbsp_i2c_init().
*/
int chbsp_i2c_write(ch_dev_t *dev_ptr, uint8_t *data, uint16_t num_bytes) {
int error = 0;
if (dev_ptr->i2c_bus_index == 0) {
error = i2c_master_write_register1_raw(dev_ptr->i2c_address, num_bytes, data); //I2C bus 0 (TWI1)
} else {
// error = i2c_master_write_register3_raw(dev_ptr->i2c_address, num_bytes, data); //I2C bus 1 (TWI3)
printf("err 'chbsp_i2c_write' on chbsp, no TWI3");
}
return error;
}
/*!
* \brief Write bytes to an I2C slave using memory addressing.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
* \param mem_addr internal memory or register address within device
* \param data data to be transmitted
* \param num_bytes length of data to be transmitted
*
* \return 0 if successful, 1 on error or NACK
*
* This function writes one or more bytes of data to an I2C slave device using an internal
* memory or register address. The remote device will write \a num_bytes bytes of
* data starting at internal memory/register address \a mem_addr.
* The I2C interface must have already been initialized using \a chbsp_i2c_init().
*/
int chbsp_i2c_mem_write(ch_dev_t *dev_ptr, uint16_t mem_addr, uint8_t *data, uint16_t num_bytes) {
int error=0;
if (dev_ptr->i2c_bus_index == 0) {
// I2C bus 0 (TWI1)
error = i2c_master_write_register1(dev_ptr->i2c_address, mem_addr, num_bytes, data);
} else if (dev_ptr->i2c_bus_index == 1) {
// I2C bus 1 (TWI3)
printf("err 'chbsp_i2c_mem_write' on chbsp, no TWI3");
}
return error;
}
/*!
* \brief Read bytes from an I2C slave.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
* \param data pointer to receive data buffer
* \param num_bytes number of bytes to read
*
* \return 0 if successful, 1 on error or NACK
*
* This function reads the specified number of bytes from an I2C slave device.
* The I2C interface must have already been initialized using \a chbsp_i2c_init().
*/
int chbsp_i2c_read(ch_dev_t *dev_ptr, uint8_t *data, uint16_t num_bytes) {
int error = 1; // default is error return
uint8_t i2c_addr = ch_get_i2c_address(dev_ptr);
uint8_t bus_num = ch_get_i2c_bus(dev_ptr);
if (bus_num == 0) {
// I2C bus 0 (TWI1)
error = i2c_master_read_register1_raw(i2c_addr, num_bytes, data);
} else if (bus_num == 1) {
// I2C bus 1 (TWI3)
error = i2c_master_read_register3_raw(i2c_addr, num_bytes, data);
}
return error;
}
/*!
* \brief Read bytes from an I2C slave using memory addressing.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
* \param mem_addr internal memory or register address within device
* \param data pointer to receive data buffer
* \param num_bytes number of bytes to read
*
* \return 0 if successful, 1 on error or NACK
*
* This function reads the specified number of bytes from an I2C slave device, using
* an internal memory or register address. The remote device will return \a num_bytes bytes
* starting at internal memory/register address \a mem_addr.
*
* The I2C interface must have already been initialized using \a chbsp_i2c_init().
*/
int chbsp_i2c_mem_read(ch_dev_t *dev_ptr, uint16_t mem_addr, uint8_t *data, uint16_t num_bytes) {
int error = 1; // default is error return
uint8_t i2c_addr = ch_get_i2c_address(dev_ptr);
uint8_t bus_num = ch_get_i2c_bus(dev_ptr);
if (bus_num == 0) {
// I2C bus 0 (TWI1)
error = i2c_master_read_register1(i2c_addr, mem_addr, num_bytes, data);
} else if (bus_num == 1) {
// I2C bus 1 (TWI3)
error = i2c_master_read_register3(i2c_addr, mem_addr, num_bytes, data);
#ifdef DEBUG_VERBOES
printf("\n err 'chbsp_i2c_mem_read' on chbsp_chirp_gd32e230f4, no TWI3 \n");
#endif
}
return error;
}
/*!
* \brief Reset I2C bus associated with device.
*
* \param dev_ptr pointer to the ch_dev_t config structure for a sensor
*
* This function performs a reset of the I2C interface for the specified device.
*/
void chbsp_i2c_reset(ch_dev_t * dev_ptr) {
uint8_t bus_num = ch_get_i2c_bus(dev_ptr);
if (bus_num == 0) { // I2C bus 0 (TWI1)
i2c_master_initialize1();
} else if (bus_num == 1) { // I2C bus 1 (TWI3)
i2c_master_initialize3();
}
}
/*!
* \brief Initialize periodic timer.
*
* \param interval_ms timer interval, in milliseconds
* \param callback_func_ptr address of routine to be called every time the timer expires
*
* \return 0 if successful, 1 if error
*
* This function initializes a periodic timer on the board. The timer is programmed
* to generate an interrupt after every \a interval_ms milliseconds.
*
* The \a callback_func_ptr parameter specifies a callback routine that will be called when the
* timer expires (and interrupt occurs). The \a chbsp_periodic_timer_handler function
* will call this function.
*/
// uint8_t chbsp_periodic_timer_init(uint16_t interval_ms, ch_timer_callback_t callback_func_ptr) {
// static bool is_hw_init_done = false;
// /* Save timer interval and callback function */
// periodic_timer_interval_ms = interval_ms;
// periodic_timer_callback_ptr = callback_func_ptr;
// /* Initialize the HW only 1 time at startup. Skip the init on subsequent calls. */
// if (!is_hw_init_done) {
// /* Configure the PMC to enable the TC module and channels */
// sysclk_enable_peripheral_clock(ID_TC0);
// sysclk_enable_peripheral_clock(ID_TC1);
// /* Create on PCK3 a 499985 Hz clock from the PLLA clock. */
// pmc_disable_pck(PMC_PCK_3);
// pmc_switch_pck_to_pllack(PMC_PCK_3, PMC_PCK_PRES(240 - 1));
// pmc_enable_pck(PMC_PCK_3);
// /* Reset all TC0 counters */
// TC0->TC_BCR = TC_BCR_SYNC;
// /* Enable TC0 - Channel 0 interrupt */
// NVIC_DisableIRQ(TC0_IRQn);
// NVIC_ClearPendingIRQ(TC0_IRQn);
// NVIC_SetPriority(TC0_IRQn, 1);
// NVIC_EnableIRQ(TC0_IRQn);
// /* Enable TC0 - Channel 1 interrupt */
// NVIC_DisableIRQ(TC1_IRQn);
// NVIC_ClearPendingIRQ(TC1_IRQn);
// NVIC_SetPriority(TC1_IRQn, 1);
// NVIC_EnableIRQ(TC1_IRQn);
// /* Create the lsepoch timer running on PCK3 and start it immediately */
// tc_init(TC0, TC_CHANNEL_LSEPOCH,
// TC_CMR_TCCLKS_TIMER_CLOCK5 | TC_CMR_WAVE | TC_CMR_WAVSEL_UP);
// tc_enable_interrupt(TC0, TC_CHANNEL_LSEPOCH, TC_IER_COVFS);
// tc_start(TC0, TC_CHANNEL_LSEPOCH);
// /* Create the ultrasound periodic timer. */
// tc_init(TC0, TC_CHANNEL_US,
// TC_CMR_TCCLKS_TIMER_CLOCK5 | TC_CMR_WAVE | TC_CMR_WAVSEL_UP);
// }
// /* Mark the HW init as done */
// is_hw_init_done = true;
// /* Convert the ODR in ms to ticks */
// ultrasound_timer_period_in_tick = get_period_in_tick(interval_ms * 1000);
// return 0;
// }
// void chbsp_periodic_timer_change_period(uint32_t new_interval_us)
// {
// uint16_t prev_expiration = ultrasound_prev_period_end_in_tick - ultrasound_timer_period_in_tick;
// ultrasound_timer_period_in_tick = get_period_in_tick(new_interval_us);
// ultrasound_prev_period_end_in_tick = prev_expiration;
// program_next_period();
// }
// uint32_t get_period_in_tick(uint32_t interval_us) {
// uint64_t timer_period_in_tick = (uint64_t) ULTRASOUND_TIMER_FREQUENCY * interval_us / 1000000;
// /* If the ODR is too slow to be handled then program a faster interrupt and decimate it */
// if (timer_period_in_tick > UINT16_MAX)
// decimation_factor = timer_period_in_tick / UINT16_MAX + 1;
// else
// decimation_factor = 1;
// /* Calculate the final tick in case a decimation is needed */
// return (uint32_t) (timer_period_in_tick / decimation_factor);
// }
// void program_next_period(void)
// {
// uint32_t time = ultrasound_prev_period_end_in_tick + ultrasound_timer_period_in_tick;
// ultrasound_prev_period_end_in_tick = time;
// tc_write_rc(TC0, TC_CHANNEL_US, (uint16_t) (time & 0xFFFF));
// }
/*!
* \brief Enable periodic timer interrupt.
*
* This function enables the interrupt associated with the periodic timer initialized by
* \a chbsp_periodic_timer_init().
*/
// void chbsp_periodic_timer_irq_enable(void) {
// /* Clear any pending CPCS before enabling it */
// tc_get_status(TC0, TC_CHANNEL_US);
// tc_enable_interrupt(TC0, TC_CHANNEL_US, TC_IER_CPCS);
// }
/*!
* \brief Disable periodic timer interrupt.
*
* This function enables the interrupt associated with the periodic timer initialized by
* \a chbsp_periodic_timer_init().
*/
// void chbsp_periodic_timer_irq_disable(void) {
// tc_disable_interrupt(TC0, TC_CHANNEL_US, TC_IDR_CPCS);
// }
/*!
* \brief Start periodic timer.
*
* \return 0 if successful, 1 if error
*
* This function starts the periodic timer initialized by \a chbsp_periodic_timer_init().
*/
// uint8_t chbsp_periodic_timer_start(void) {
// decimation_counter = 0;
// /* The timer start done at the very end is resetting the counter */
// ultrasound_prev_period_end_in_tick = 0;
// program_next_period();
// /* Start the HW counter (this resets the counter */
// tc_start(TC0, TC_CHANNEL_US);
// return 0;
// }
/*!
* \brief Turn on an LED on the board.
*
* This function turns on an LED on the board.
*
* The \a dev_num parameter contains the device number of a specific sensor. This routine
* will turn on the LED on the Chirp sensor daughterboard that is next to the specified
* sensor.
*/
void chbsp_led_on(uint8_t led_num) {
sensor_led_on();
}
/*!
* \brief Turn off an LED on the board.
*
* This function turns off an LED on the board.
*
* The \a dev_num parameter contains the device number of a specific sensor. This routine
* will turn off the LED on the Chirp sensor daughterboard that is next to the specified
* sensor.
*/
void chbsp_led_off(uint8_t led_num) {
sensor_led_off();
}
/*!
* \brief Toggles an LED on the board.
*
* This function toggles an LED on the board.
*
* The \a dev_num parameter contains the device number of a specific sensor. This routine
* will toggles the LED on the Chirp sensor daughterboard that is next to the specified
* sensor.
*/
void chbsp_led_toggle(uint8_t led_num) {
sensor_led_toggle();
}
/*!
* \brief Output a text string via serial interface
*
* \param str pointer to a string of characters to be output
*
* This function prints debug information to the console.
*/
void chbsp_print_str(char *str) {
printf("%s", str);
}
/*!
* \brief Return the current time in ms
*
* This function returns the system current time in ms.
*/
// uint32_t chbsp_timestamp_ms(void) {
// uint32_t time = time_get_in_us();
// return (time / 1000);
// }
/************* End of file chbsp_chirp_smartsonic.c -- Copyright 2016-2019 Chirp Microsystems **********/

View File

@@ -0,0 +1,88 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2020 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively “Software”) is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
/**
* \file chirp_board_config.h
*
* This file defines required symbols used to build an application with the Chirp SonicLib
* API and driver. These symbols are used for static array allocations and counters in SonicLib
* (and often applications), and are based on the number of specific resources on the target board.
*
* Two symbols must be defined:
* CHIRP_MAX_NUM_SENSORS - the number of possible sensor devices (i.e. the number of sensor ports)
* CHIRP_NUM_I2C_BUSES - the number of I2C buses on the board that are used for those sensor ports
*
* This file must be in the C pre-processor include path when the application is built with SonicLib
* and this board support package.
*/
#ifndef CHIRP_BOARD_CONFIG_H
#define CHIRP_BOARD_CONFIG_H
/* Settings for the Chirp SmartSonic board */
#define CHIRP_MAX_NUM_SENSORS 1 // maximum possible number of sensor devices
#define CHIRP_NUM_I2C_BUSES 1 // number of I2C buses used by sensors
#define I2C0_MASTER_ADDRESS7 0xA0
#define I2C0_SPEED 400000
/* PROG_EN GPIO */
#define CHIRP_PIN_PROG_PORT GPIOA
#define CHIRP_PIN_PROG_PIN GPIO_PIN_5
#define CHIRP_PIN_PROG_CLK RCU_GPIOA
/* RST GPIO */
#define CHIRP_PIN_RST_PORT GPIOA
#define CHIRP_PIN_RST_PIN GPIO_PIN_6
#define CHIRP_PIN_RST_CLK RCU_GPIOA
/* INT GPIO */
#define CHIRP_PIN_INT_PORT GPIOA
#define CHIRP_PIN_INT_PIN GPIO_PIN_7
#define CHIRP_PIN_INT_CLK RCU_GPIOA
#define CHIRP_EXTI_INT_PORT EXTI_SOURCE_GPIOA
#define CHIRP_EXTI_INT_PIN EXTI_SOURCE_PIN7
#define CHIRP_EXTI_INT_LINE EXTI_7
/* LED GPIO */
#define CHIRP_PIN_LED_PORT GPIOB
#define CHIRP_PIN_LED_PIN GPIO_PIN_1
#define CHIRP_PIN_LED_CLK RCU_GPIOB
/* IIC Config */
#define CHIRP_PIN_IIC_BUS I2C0
#define CHIRP_PIN_IIC_PORT GPIOF
#define CHIRP_PIN_IIC_SDA_PIN GPIO_PIN_0
#define CHIRP_PIN_IIC_SCL_PIN GPIO_PIN_1
#define CHIRP_PIN_IIC_PIN_CLK RCU_GPIOF
#define CHIRP_PIN_IIC_CLK RCU_I2C0
#define CHIRP_PIN_IIC_DMA_CLK RCU_DMA
#define CHIRP_ADC_NONE
// #define DEBUG_VERBOES
/* Deactivate use of debug I2C interface */
#define USE_STD_I2C_FOR_IQ (1)
#endif /* CHIRP_BOARD_CONFIG_H */

View File

@@ -0,0 +1,83 @@
/*
Copyright <20> 2016-2019, Chirp Microsystems. All rights reserved.
All rights reserved.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL CHIRP MICROSYSTEMS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the authors of this program by email at support@chirpmicro.com
or by mail at 2560 Ninth Street, Suite 220, Berkeley, CA 94710.
*/
/** \file chirp_smartsonic.h */
#ifndef CHIRP_SMARTSONIC_H
#define CHIRP_SMARTSONIC_H
#include "soniclib.h"
#include "chirp_board_config.h"
#include "app_config.h"
/* Standard symbols used in board support package - use values from config header */
#define CHBSP_MAX_DEVICES CHIRP_MAX_NUM_SENSORS
#define CHBSP_NUM_I2C_BUSES CHIRP_NUM_I2C_BUSES
#if defined(CHIRP_RTC_CAL_PULSE_LEN_MS)
/** Length of real-time clock calibration pulse, in milliseconds :
* length of pulse applied to sensor INT line during clock cal
*/
#define CHBSP_RTC_CAL_PULSE_MS CHIRP_RTC_CAL_PULSE_LEN_MS
#else
/* Default value */
#define CHBSP_RTC_CAL_PULSE_MS (100)
#endif
/* I2C Address assignments for each possible device */
#define CHIRP_I2C_ADDRS {45}
#define CHIRP_I2C_BUSES {0}
/* IRQ assignments */
#define TWI1_IRQn FLEXCOM1_IRQn
#define TWI3_IRQn FLEXCOM3_IRQn
/* Processor sleep mode */
#define PROC_SLEEP_MODE SAM_PM_SMODE_SLEEP_WFI /* wait for interrupt */
/* Structure to track non-blocking I2C transaction data */
typedef struct {
uint8_t *buf_ptr; /* pointer to data buffer */
uint16_t num_bytes; /* number of bytes to transfer */
} i2c_trans_data_t;
/* TC channel used for the ultrasound timer and lsepoch of the system */
#define TC_CHANNEL_LSEPOCH (0)
#define TC_CHANNEL_US (1)
/* Define the HW frequency of the TC used for the ultrasound periodic timer */
#define ULTRASOUND_TIMER_FREQUENCY (499985) /* = 32768 * 3662 / 240 */
#define ULTRASOUND_DECIMATION_FACTOR (1)
extern uint32_t chirp_pin_prog[CHBSP_MAX_DEVICES];
extern uint32_t chirp_pin_io[CHBSP_MAX_DEVICES];
extern uint32_t chirp_pin_io_irq[CHBSP_MAX_DEVICES];
extern ch_group_t chirp_group;
extern i2c_trans_data_t i2c_nb_transactions[CHBSP_NUM_I2C_BUSES]; // array of structures to track non-blocking I2C transactions
void sensor_led_on(void);
void sensor_led_off(void);
void sensor_led_toggle(void);
void indicate_alive(void);
extern ch_io_int_callback_t io_int_callback_ptr; // pointer to sensor I/O interrupt callback function
extern void periodic_timer_callback(void);
#endif /* CHIRP_SMARTSONIC_H */

762
CHIRP/board/i2c.c Normal file
View File

@@ -0,0 +1,762 @@
#include <stdio.h>
#include <stdint.h>
#include "gd32e23x.h"
#include "i2c.h"
#include "gd32e23x.h"
#include "chirp_board_config.h"
#include "board_init.h"
/*!
\brief Enable IIC0 & NVIC
\param[in] none
\param[out] none
\retval none
*/
void i2c_master_initialize1(void)
{
/* IIC config */
rcu_periph_clock_enable(CHIRP_PIN_IIC_CLK);
i2c_clock_config(CHIRP_PIN_IIC_BUS, I2C0_SPEED, I2C_DTCY_2);
i2c_mode_addr_config(CHIRP_PIN_IIC_BUS, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C0_MASTER_ADDRESS7);
i2c_enable(CHIRP_PIN_IIC_BUS);
i2c_ack_config(CHIRP_PIN_IIC_BUS, I2C_ACK_ENABLE);
/* enable I2C0 NVIC */
nvic_irq_enable(I2C0_ER_IRQn, 1);
nvic_irq_enable(I2C0_EV_IRQn, 3);
}
/*!
\brief No TWI3(IIC3),no operation err log.
\param[in] none
\param[out] none
\retval none
*/
void i2c_master_initialize3(void)
{
__NOP();
#ifdef DEBUG_VERBOES
printf("\n[DebugVerboes]i2c_master_initialize3 @ i2c.c, no TWI3 \n");
#endif
}
/*!
\brief Only Init TWI1(IIC1),No TWI3(IIC3),no operation err log.
\param[in] none
\param[out] none
\retval none
*/
void i2c_master_init(void)
{
i2c_master_initialize1();
i2c_master_initialize3();
gpio_mode_set(CHIRP_PIN_LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, CHIRP_PIN_LED_PIN);
}
/*!
\brief Deinit TWI1(IIC1).
\param[in] none
\param[out] none
\retval none
*/
void i2c_master_deinit1(void)
{
rcu_periph_clock_disable(CHIRP_PIN_IIC_CLK);
i2c_disable(CHIRP_PIN_IIC_BUS);
}
/*!
\brief No TWI3(IIC3),no operation err log.
\param[in] none
\param[out] none
\retval none
*/
void i2c_master_deinit3(void)
{
__NOP();
#ifdef DEBUG_VERBOES
printf("\n[DebugVerboes]i2c_master_deinit3 @ i2c.c, no TWI3 Pin \n");
#endif
}
/*!
\brief TWI1(IIC0) read data from the IIC Slave Device
\param[in] Address: the IIC Slave Device's IIC Device Address
\param[in] RegisterAddr: the IIC Slave Device's internal address to start reading from
\param[in] RegisterLen: number of bytes to reads from the IIC Slave Device
\param[in] RegisterValue: pointer to the buffer that receives the data read from the IIC Slave Device
\param[out] RegisterValue: pointer to the buffer that receives the data read from the IIC Slave Device
\retval IIC_SUCCESS
*/
uint8_t i2c_master_read_register1(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue){
uint8_t state = I2C_START;
uint8_t read_cycle = 0;
uint16_t timeout = 0;
uint8_t i2c_timeout_flag = 0;
unsigned char IIC_SLAVE_ADDR = (Address << 1);
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
while (!(i2c_timeout_flag))
{
switch (state)
{
case I2C_START:
if(RESET == read_cycle)
{
/* i2c master sends start signal only when the bus is idle */
while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < i2c_timeout_flag))
{
timeout ++;
}
if(timeout < I2C_TIME_OUT)
{
/* whether to send ACK or not for the next byte */
if(2 == RegisterLen) {
i2c_ackpos_config(I2C0, I2C_ACKPOS_NEXT);
}
} else {
i2c_bus_reset();
timeout = 0;
state = I2C_START;
printf("i2c bus is busy in READ!\n");
}
}
/* send the start signal */
i2c_start_on_bus(I2C0);
timeout = 0;
state = I2C_SEND_ADDR;
break;
case I2C_SEND_ADDR:
/* i2c master sends START signal successfully */
while((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT))
{
timeout++;
}
if(timeout < I2C_TIME_OUT)
{
if(RESET == read_cycle)
{
i2c_master_addressing(I2C0, IIC_SLAVE_ADDR, I2C_TRANSMITTER);
state = I2C_CLEAR_ADDRESS_FLAG;
} else {
i2c_master_addressing(I2C0, IIC_SLAVE_ADDR, I2C_RECEIVER);
if(RegisterLen < 3) {
/* disable acknowledge */
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
}
state = I2C_CLEAR_ADDRESS_FLAG;
}
timeout = 0;
} else {
timeout = 0;
state = I2C_START;
read_cycle = 0;
printf("i2c master sends start signal timeout in READ!\n");
}
break;
case I2C_CLEAR_ADDRESS_FLAG:
/* address flag set means i2c slave sends ACK */
while((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT))
{
timeout++;
}
if(timeout < I2C_TIME_OUT)
{
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
if((SET == read_cycle) && (1 == RegisterLen)) {
/* send a stop condition to I2C bus */
i2c_stop_on_bus(I2C0);
}
timeout = 0;
state = I2C_TRANSMIT_DATA;
} else {
timeout = 0;
state = I2C_START;
read_cycle = 0;
printf("i2c master clears address flag timeout in READ!\n");
}
break;
case I2C_TRANSMIT_DATA:
if(RESET == read_cycle) {
/* wait until the transmit data buffer is empty */
while((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
/* send the EEPROM's internal address to write to : only one byte address */
i2c_data_transmit(I2C0, RegisterAddr);
timeout = 0;
} else {
timeout = 0;
state = I2C_START;
read_cycle = 0;
printf("i2c master wait data buffer is empty timeout in READ!\n");
}
/* wait until BTC bit is set */
while((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
timeout = 0;
state = I2C_START;
read_cycle++;
} else {
timeout = 0;
state = I2C_START;
read_cycle = 0;
printf("i2c master sends i2c_master_read_register1 internal address timeout in READ!\n");
}
} else {
while(RegisterLen) {
timeout++;
if(3 == RegisterLen) {
/* wait until BTC bit is set */
while(!i2c_flag_get(I2C0, I2C_FLAG_BTC));
/* disable acknowledge */
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
}
if(2 == RegisterLen) {
/* wait until BTC bit is set */
while(!i2c_flag_get(I2C0, I2C_FLAG_BTC));
/* send a stop condition to I2C bus */
i2c_stop_on_bus(I2C0);
}
/* wait until RBNE bit is set */
if(i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {
/* read a byte from the EEPROM */
*RegisterValue = i2c_data_receive(I2C0);
/* point to the next location where the byte read will be saved */
RegisterValue++;
/* decrement the read bytes counter */
RegisterLen--;
timeout = 0;
}
if(timeout > I2C_TIME_OUT) {
timeout = 0;
state = I2C_START;
read_cycle = 0;
printf("i2c master sends data timeout in READ!\n");
}
}
timeout = 0;
state = I2C_STOP;
}
break;
case I2C_STOP:
/* i2c master sends STOP signal successfully */
while((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
timeout = 0;
state = I2C_END;
i2c_timeout_flag = I2C_OK;
} else {
timeout = 0;
state = I2C_START;
read_cycle = 0;
printf("i2c master sends stop signal timeout in READ!\n");
}
break;
default:
state = I2C_START;
read_cycle = 0;
i2c_timeout_flag = I2C_OK;
timeout = 0;
printf("i2c master sends start signal in READ.\n");
break;
}
}
return IIC_SUCCESS;
}
/*!
\brief TWI3(none) read data from the IIC Slave Device
\param[in] Address: the IIC Slave Device's IIC Device Address
\param[in] RegisterAddr: the IIC Slave Device's internal address to start reading from
\param[in] RegisterLen: number of bytes to reads from the IIC Slave Device
\param[in] RegisterValue: pointer to the buffer that receives the data read from the IIC Slave Device
\param[out] RegisterValue: pointer to the buffer that receives the data read from the IIC Slave Device
\retval IIC_SUCCESS
\note No TWI3(IIC3) - No operation - Error log.
*/
uint8_t i2c_master_read_register3(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue){
__NOP();
#ifdef DEBUG_VERBOES
printf("\n[DebugVerboes]i2c_master_read_register3 @ i2c.c, no TWI3 \n");
#endif
return IIC_SUCCESS;
}
/*!
\brief TWI1(IIC0) read data from the IIC Slave Device
\param[in] Address: the IIC Slave Device's IIC Device Address
\param[in] len: number of bytes to reads from the IIC Slave Device
\param[in] data: pointer to the buffer that receives the data read from the IIC Slave Device
\param[out] data: pointer to the buffer that receives the data read from the IIC Slave Device
\retval IIC_SUCCESS
*/
uint8_t i2c_master_read_register1_raw(unsigned char Address, unsigned short len, unsigned char *data){
uint8_t state = I2C_START;
// uint8_t read_cycle = 0;
uint16_t timeout = 0;
uint8_t i2c_timeout_flag = 0;
unsigned char IIC_SLAVE_ADDR = (Address << 1);
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
while (!(i2c_timeout_flag))
{
switch (state)
{
case I2C_START:
/* i2c master sends start signal only when the bus is idle */
while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < i2c_timeout_flag))
{
timeout ++;
}
if(timeout < I2C_TIME_OUT)
{
/* whether to send ACK or not for the next byte */
if(2 == len) {
i2c_ackpos_config(I2C0, I2C_ACKPOS_NEXT);
}
} else {
i2c_bus_reset();
timeout = 0;
state = I2C_START;
printf("i2c bus is busy in READ!\n");
}
/* send the start signal */
i2c_start_on_bus(I2C0);
timeout = 0;
state = I2C_SEND_ADDR;
break;
case I2C_SEND_ADDR:
/* i2c master sends START signal successfully */
while((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT))
{
timeout++;
}
if(timeout < I2C_TIME_OUT)
{
i2c_master_addressing(I2C0, IIC_SLAVE_ADDR, I2C_RECEIVER);
if(len < 3) {
/* disable acknowledge */
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
}
state = I2C_CLEAR_ADDRESS_FLAG;
timeout = 0;
} else {
timeout = 0;
state = I2C_START;
// read_cycle = 0;
printf("i2c master sends start signal timeout in READ!\n");
}
break;
case I2C_CLEAR_ADDRESS_FLAG:
/* address flag set means i2c slave sends ACK */
while((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT))
{
timeout++;
}
if(timeout < I2C_TIME_OUT)
{
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
timeout = 0;
state = I2C_TRANSMIT_DATA;
} else {
timeout = 0;
state = I2C_START;
// read_cycle = 0;
printf("i2c master clears address flag timeout in READ!\n");
}
break;
case I2C_TRANSMIT_DATA:
while(len) {
timeout++;
if(3 == len) {
/* wait until BTC bit is set */
while(!i2c_flag_get(I2C0, I2C_FLAG_BTC));
/* disable acknowledge */
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
}
if(2 == len) {
/* wait until BTC bit is set */
while(!i2c_flag_get(I2C0, I2C_FLAG_BTC));
/* send a stop condition to I2C bus */
i2c_stop_on_bus(I2C0);
}
/* wait until RBNE bit is set */
if(i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {
/* read a byte from the EEPROM */
*data = i2c_data_receive(I2C0);
/* point to the next location where the byte read will be saved */
data++;
/* decrement the read bytes counter */
len--;
timeout = 0;
}
if(timeout > I2C_TIME_OUT) {
timeout = 0;
state = I2C_START;
// read_cycle = 0;
printf("i2c master sends data timeout in READ!\n");
}
}
timeout = 0;
state = I2C_STOP;
// }
break;
case I2C_STOP:
/* i2c master sends STOP signal successfully */
while((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
timeout = 0;
state = I2C_END;
i2c_timeout_flag = I2C_OK;
} else {
timeout = 0;
state = I2C_START;
// read_cycle = 0;
printf("i2c master sends stop signal timeout in READ!\n");
}
break;
default:
state = I2C_START;
// read_cycle = 0;
i2c_timeout_flag = I2C_OK;
timeout = 0;
printf("i2c master sends start signal in READ.\n");
break;
}
}
return IIC_SUCCESS;
}
/*!
\brief TWI3(none) read data from the IIC Slave Device with no regisiter address
\param[in] Address: the IIC Slave Device's IIC Device Address
\param[in] len: number of bytes to reads from the IIC Slave Device
\param[in] data: pointer to the buffer that receives the data read from the IIC Slave Device
\param[out] data: pointer to the buffer that receives the data read from the IIC Slave Device
\retval IIC_SUCCESS
\note No TWI3(IIC3) - No operation - Error log.
*/
uint8_t i2c_master_read_register3_raw(unsigned char Address, unsigned short len, unsigned char *data){
__NOP();
#ifdef DEBUG_VERBOES
printf("\n[DebugVerboes]i2c_master_read_register3_raw @ i2c.c, no TWI3 \n");
#endif
return IIC_SUCCESS;
}
/*!
\brief TWI1(IIC0) write data to the IIC Slave Device
\param[in] Address: the IIC Slave Device's IIC Device Address
\param[in] RegisterAddr: the IIC Slave Device's internal address to start writing to
\param[in] RegisterLen: number of bytes to write to the IIC Slave Device
\param[in] RegisterValue: pointer to the buffer that transfer the data write to the IIC Slave Device
\param[out] RegisterValue: pointer to the buffer that transfer the data write to the IIC Slave Device
\retval IIC_SUCCESS
*/
uint8_t i2c_master_write_register1(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue)
{
uint8_t state = I2C_START;
uint16_t timeout = 0;
uint8_t i2c_timeout_flag = 0;
unsigned char IIC_SLAVE_ADDR = (Address << 1);
/* enable acknowledge */
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
while(!(i2c_timeout_flag)) {
switch(state) {
case I2C_START:
/* i2c master sends start signal only when the bus is idle */
while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
i2c_start_on_bus(I2C0);
timeout = 0;
state = I2C_SEND_ADDR;
} else {
i2c_bus_reset();
timeout = 0;
state = I2C_START;
printf("i2c bus is busy in WRITE!\n");
}
break;
case I2C_SEND_ADDR:
/* i2c master sends START signal successfully */
while((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
i2c_master_addressing(I2C0, IIC_SLAVE_ADDR, I2C_TRANSMITTER);
timeout = 0;
state = I2C_CLEAR_ADDRESS_FLAG;
} else {
timeout = 0;
state = I2C_START;
printf("i2c master sends start signal timeout in WRITE!\n");
}
break;
case I2C_CLEAR_ADDRESS_FLAG:
/* address flag set means i2c slave sends ACK */
while((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
timeout = 0;
state = I2C_TRANSMIT_DATA;
} else {
timeout = 0;
state = I2C_START;
printf("i2c master clears address flag timeout in WRITE!\n");
}
break;
case I2C_TRANSMIT_DATA:
/* wait until the transmit data buffer is empty */
while((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
/* send the EEPROM's internal address to write to : only one byte address */
i2c_data_transmit(I2C0, RegisterAddr);
timeout = 0;
} else {
timeout = 0;
state = I2C_START;
printf("i2c master sends i2c_master_write_register1 internal address timeout in WRITE!\n");
}
/* wait until BTC bit is set */
while((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
timeout = 0;
} else {
timeout = 0;
state = I2C_START;
printf("i2c master sends data timeout in WRITE!\n");
}
while(RegisterLen--) {
i2c_data_transmit(I2C0, *RegisterValue);
/* point to the next byte to be written */
RegisterValue++;
/* wait until BTC bit is set */
while((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
timeout = 0;
} else {
timeout = 0;
state = I2C_START;
printf("i2c master sends data timeout in WRITE!\n");
}
}
timeout = 0;
state = I2C_STOP;
break;
case I2C_STOP:
/* send a stop condition to I2C bus */
i2c_stop_on_bus(I2C0);
/* i2c master sends STOP signal successfully */
while((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
timeout = 0;
state = I2C_END;
i2c_timeout_flag = I2C_OK;
} else {
timeout = 0;
state = I2C_START;
printf("i2c master sends stop signal timeout in WRITE!\n");
}
break;
default:
state = I2C_START;
i2c_timeout_flag = I2C_OK;
timeout = 0;
printf("i2c master sends start signal in WRITE.\n");
break;
}
}
return IIC_SUCCESS;
}
/*!
\brief TWI3(none) write data to the IIC Slave Device
\param[in] Address: the IIC Slave Device's IIC Device Address
\param[in] RegisterAddr: the IIC Slave Device's internal address to start writing to
\param[in] RegisterLen: number of bytes to write to the IIC Slave Device
\param[in] RegisterValue: pointer to the buffer that transfer the data write to the IIC Slave Device
\param[out] RegisterValue: pointer to the buffer that transfer the data write to the IIC Slave Device
\retval IIC_SUCCESS
\note No TWI3(IIC3) - No operation - Error log.
*/
uint8_t i2c_master_write_register3(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue){
__NOP();
#ifdef DEBUG_VERBOES
printf("\n[DebugVerboes]i2c_master_write_register3 @ i2c.c, no TWI3 \n");
#endif
return IIC_SUCCESS;
}
/*!
\brief TWI1(IIC0) write data to the IIC Slave Device with no regisiter address
\param[in] Address: the IIC Slave Device's IIC Device Address
\param[in] len: number of bytes to write to the IIC Slave Device
\param[in] data: pointer to the buffer that transfer the data write to the IIC Slave Device
\param[out] data: pointer to the buffer that transfer the data write to the IIC Slave Device
\retval IIC_SUCCESS
*/
uint8_t i2c_master_write_register1_raw(unsigned char Address, unsigned short len, unsigned char *data){
uint8_t state = I2C_START;
uint16_t timeout = 0;
uint8_t i2c_timeout_flag = 0;
unsigned char IIC_SLAVE_ADDR = (Address << 1);
/* enable acknowledge */
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
while(!(i2c_timeout_flag)) {
switch(state) {
case I2C_START:
/* i2c master sends start signal only when the bus is idle */
while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
i2c_start_on_bus(I2C0);
timeout = 0;
state = I2C_SEND_ADDR;
} else {
i2c_bus_reset();
timeout = 0;
state = I2C_START;
printf("i2c bus is busy in WRITE!\n");
}
break;
case I2C_SEND_ADDR:
/* i2c master sends START signal successfully */
while((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
i2c_master_addressing(I2C0, IIC_SLAVE_ADDR, I2C_TRANSMITTER);
timeout = 0;
state = I2C_CLEAR_ADDRESS_FLAG;
} else {
timeout = 0;
state = I2C_START;
printf("i2c master sends start signal timeout in WRITE!\n");
}
break;
case I2C_CLEAR_ADDRESS_FLAG:
/* address flag set means i2c slave sends ACK */
while((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
timeout = 0;
state = I2C_TRANSMIT_DATA;
} else {
timeout = 0;
state = I2C_START;
printf("i2c master clears address flag timeout in WRITE!\n");
}
break;
case I2C_TRANSMIT_DATA:
/* wait until the transmit data buffer is empty */
while((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
while(len--) {
i2c_data_transmit(I2C0, *data);
/* point to the next byte to be written */
data++;
/* wait until BTC bit is set */
while((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
timeout = 0;
} else {
timeout = 0;
state = I2C_START;
printf("i2c master sends data timeout in WRITE!\n");
}
}
timeout = 0;
state = I2C_STOP;
break;
case I2C_STOP:
/* send a stop condition to I2C bus */
i2c_stop_on_bus(I2C0);
/* i2c master sends STOP signal successfully */
while((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
timeout = 0;
state = I2C_END;
i2c_timeout_flag = I2C_OK;
} else {
timeout = 0;
state = I2C_START;
printf("i2c master sends stop signal timeout in WRITE!\n");
}
break;
default:
state = I2C_START;
i2c_timeout_flag = I2C_OK;
timeout = 0;
printf("i2c master sends start signal in WRITE.\n");
break;
}
}
return IIC_SUCCESS;
}
/*!
\brief TWI3(none) write data to the IIC Slave Device with no regisiter address
\param[in] Address: the IIC Slave Device's IIC Device Address
\param[in] len: number of bytes to write to the IIC Slave Device
\param[in] data: pointer to the buffer that transfer the data write to the IIC Slave Device
\param[out] data: pointer to the buffer that transfer the data write to the IIC Slave Device
\retval IIC_SUCCESS
\note No TWI3(IIC3) - No operation - Error log.
*/
uint8_t i2c_master_write_register3_raw(unsigned char Address, unsigned short len, unsigned char *data){
__NOP();
#ifdef DEBUG_VERBOES
printf("\n[DebugVerboes]i2c_master_write_register3_raw @ i2c.c, no TWI3 \n");
#endif
return IIC_SUCCESS;
}

55
CHIRP/board/i2c.h Normal file
View File

@@ -0,0 +1,55 @@
#ifndef I2C_H
#define I2C_H
#define I2C_TIME_OUT (uint16_t)(5000)
#define I2C_OK 1
#define I2C_FAIL 0
#define I2C_END 1
typedef enum {
I2C_START = 0,
I2C_SEND_ADDR,
I2C_CLEAR_ADDRESS_FLAG,
I2C_TRANSMIT_DATA,
I2C_STOP
} i2c_process_enum;
/**
* \brief Return codes for IIC APIs.
* @{
*/
#define IIC_SUCCESS 0
#define IIC_INVALID_ARGUMENT 1
#define IIC_ARBITRATION_LOST 2
#define IIC_NO_CHIP_FOUND 3
#define IIC_RECEIVE_OVERRUN 4
#define IIC_RECEIVE_NACK 5
#define IIC_SEND_OVERRUN 6
#define IIC_SEND_NACK 7
#define IIC_BUSY 8
#define IIC_ERROR_TIMEOUT 9
/**
* @}
*/
void i2c_master_initialize1(void);
void i2c_master_initialize3(void);
void i2c_master_init(void);
void i2c_master_deinit1(void);
void i2c_master_deinit3(void);
uint8_t i2c_master_read_register1(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue);
uint8_t i2c_master_read_register3(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue);
uint8_t i2c_master_read_register1_raw(unsigned char Address, unsigned short len, unsigned char *data);
uint8_t i2c_master_read_register3_raw(unsigned char Address, unsigned short len, unsigned char *data);
uint8_t i2c_master_write_register1(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue);
uint8_t i2c_master_write_register3(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue);
uint8_t i2c_master_write_register1_raw(unsigned char Address, unsigned short len, unsigned char *data);
uint8_t i2c_master_write_register3_raw(unsigned char Address, unsigned short len, unsigned char *data);
#endif /* I2C_H */