mirror of
https://github.com/Ralim/IronOS.git
synced 2025-02-26 07:53:55 +00:00
Remove unused hal
This commit is contained in:
@@ -41,7 +41,6 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t read_address, uint8_t *p_b
|
||||
i2cCfg.subAddrSize = 1; // one byte address
|
||||
|
||||
err = I2C_MasterReceiveBlocking(I2C0_ID, &i2cCfg);
|
||||
// MSG((char *)"I2C Mem_Read %02X - %d - %d\r\n", DevAddress >> 1, err, number_of_byte);
|
||||
bool res = err == SUCCESS;
|
||||
if (!res) {
|
||||
I2C_Unstick();
|
||||
@@ -64,7 +63,6 @@ bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *p_bu
|
||||
i2cCfg.subAddrSize = 1; // one byte address
|
||||
|
||||
err = I2C_MasterSendBlocking(I2C0_ID, &i2cCfg);
|
||||
// MSG((char *)"I2C Mem_Write %02X - %d\r\n", DevAddress >> 1, err);
|
||||
bool res = err == SUCCESS;
|
||||
if (!res) {
|
||||
I2C_Unstick();
|
||||
@@ -120,12 +118,10 @@ bool FRToSI2C::wakePart(uint16_t DevAddress) {
|
||||
i2cCfg.subAddrSize = 0;
|
||||
|
||||
err = I2C_MasterReceiveBlocking(I2C0_ID, &i2cCfg);
|
||||
// MSG((char *)"I2C wakePart %02X - %d\r\n", DevAddress >> 1, err);
|
||||
bool res = err == SUCCESS;
|
||||
if (!res) {
|
||||
I2C_Unstick();
|
||||
}
|
||||
unlock();
|
||||
// MSG((char *)"I2C probe done \r\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ extern "C" {
|
||||
#include "bl702_glb.h"
|
||||
#include "bl702_pwm.h"
|
||||
#include "bl702_timer.h"
|
||||
#include "hal_clock.h"
|
||||
}
|
||||
|
||||
#define ADC_Filter_Smooth 4
|
||||
@@ -47,11 +46,9 @@ void adc_fifo_irq(void) {
|
||||
break;
|
||||
|
||||
default:
|
||||
// MSG((char *)"ADC Invalid chan %d\r\n", source);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// MSG((char *)"ADC Reading %d %d %d\r\n", ADC_Temp.average(), ADC_Vin.average(), ADC_Tip.average());
|
||||
if (wakePID) {
|
||||
// unblock the PID controller thread
|
||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
@@ -140,8 +137,6 @@ void setTipPWM(const uint8_t pulse, const bool shouldUseFastModePWM) {
|
||||
// disabled if the PID task is not scheduled often enough.
|
||||
pendingPWM = pulse;
|
||||
fastPWM = shouldUseFastModePWM;
|
||||
|
||||
// MSG((char *)"PWM Output %d, %d\r\n", pulse, (int)shouldUseFastModePWM);
|
||||
}
|
||||
extern osThreadId POWTaskHandle;
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
#define TIP_TEMP_Pin GPIO_PIN_19
|
||||
#define TIP_TEMP_ADC_CHANNEL ADC_CHAN9
|
||||
|
||||
#define Debug_Pin GPIO_PIN_14
|
||||
#define Debug2_Pin GPIO_PIN_15
|
||||
|
||||
#define VIN_Pin GPIO_PIN_18
|
||||
#define VIN_ADC_CHANNEL ADC_CHAN8
|
||||
#define OLED_RESET_Pin GPIO_PIN_3
|
||||
|
||||
@@ -29,6 +29,8 @@ void hardware_init() {
|
||||
gpio_set_mode(TMP36_INPUT_Pin, GPIO_INPUT_MODE);
|
||||
gpio_set_mode(TIP_TEMP_Pin, GPIO_INPUT_MODE);
|
||||
gpio_set_mode(VIN_Pin, GPIO_INPUT_MODE);
|
||||
gpio_set_mode(Debug_Pin, GPIO_OUTPUT_MODE);
|
||||
gpio_set_mode(Debug2_Pin, GPIO_OUTPUT_MODE);
|
||||
|
||||
setup_timer_scheduler();
|
||||
setup_adc();
|
||||
|
||||
@@ -17,7 +17,6 @@ extern "C" {
|
||||
#include "bl702_pwm.h"
|
||||
#include "bl702_timer.h"
|
||||
#include "hal_adc.h"
|
||||
#include "hal_clock.h"
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
#ifndef __HAL_ACOMP_H__
|
||||
#define __HAL_ACOMP_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hal_common.h"
|
||||
|
||||
enum acomp_channel_type {
|
||||
ACOMP_CHANNEL_ADC_CHANNEL0, /*!< Analog compare channel,ADC input channel 0 */
|
||||
ACOMP_CHANNEL_ADC_CHANNEL1, /*!< Analog compare channel,ADC input channel 1 */
|
||||
ACOMP_CHANNEL_ADC_CHANNEL2, /*!< Analog compare channel,ADC input channel 2 */
|
||||
ACOMP_CHANNEL_ADC_CHANNEL3, /*!< Analog compare channel,ADC input channel 3 */
|
||||
ACOMP_CHANNEL_ADC_CHANNEL4, /*!< Analog compare channel,ADC input channel 4 */
|
||||
ACOMP_CHANNEL_ADC_CHANNEL5, /*!< Analog compare channel,ADC input channel 5 */
|
||||
ACOMP_CHANNEL_ADC_CHANNEL6, /*!< Analog compare channel,ADC input channel 6 */
|
||||
ACOMP_CHANNEL_ADC_CHANNEL7, /*!< Analog compare channel,ADC input channel 7 */
|
||||
ACOMP_CHANNEL_DAC_CHANNELA, /*!< Analog compare channel,DAC output channel A */
|
||||
ACOMP_CHANNEL_DAC_CHANNELB, /*!< Analog compare channel,DAC output channel B */
|
||||
ACOMP_CHANNEL_VREF_1P2V, /*!< Analog compare channel,1.2V ref voltage */
|
||||
ACOMP_CHANNEL_0P375VBAT, /*!< Analog compare channel,6/16Vbat */
|
||||
ACOMP_CHANNEL_0P25VBAT, /*!< Analog compare channel,4/16Vbat */
|
||||
ACOMP_CHANNEL_0P1875VBAT, /*!< Analog compare channel,3/16Vbat */
|
||||
ACOMP_CHANNEL_0P3125VBAT, /*!< Analog compare channel,5/16Vbat */
|
||||
ACOMP_CHANNEL_VSS, /*!< Analog compare channel,vss */
|
||||
};
|
||||
|
||||
enum acomp_hysteresis_vol_type {
|
||||
ACOMP_HYSTERESIS_VOLT_NONE, /*!< Analog compare hysteresis voltage none */
|
||||
ACOMP_HYSTERESIS_VOLT_10MV, /*!< Analog compare hysteresis voltage 10mv */
|
||||
ACOMP_HYSTERESIS_VOLT_20MV, /*!< Analog compare hysteresis voltage 20mv */
|
||||
ACOMP_HYSTERESIS_VOLT_30MV, /*!< Analog compare hysteresis voltage 30mv */
|
||||
ACOMP_HYSTERESIS_VOLT_40MV, /*!< Analog compare hysteresis voltage 40mv */
|
||||
ACOMP_HYSTERESIS_VOLT_50MV, /*!< Analog compare hysteresis voltage 50mv */
|
||||
ACOMP_HYSTERESIS_VOLT_60MV, /*!< Analog compare hysteresis voltage 60mv */
|
||||
ACOMP_HYSTERESIS_VOLT_70MV, /*!< Analog compare hysteresis voltage 70mv */
|
||||
};
|
||||
|
||||
enum acomp_it_type {
|
||||
ACOMP_POSITIVE_IT = 1 << 0,
|
||||
ACOMP_NEGATIVE_IT = 1 << 1,
|
||||
};
|
||||
|
||||
typedef struct acomp_device {
|
||||
enum acomp_channel_type pos_ch;
|
||||
enum acomp_channel_type neg_ch;
|
||||
enum acomp_hysteresis_vol_type pos_hysteresis_vol;
|
||||
enum acomp_hysteresis_vol_type neg_hysteresis_vol;
|
||||
} acomp_device_t;
|
||||
|
||||
void acomp_init(uint8_t idx,acomp_device_t *device);
|
||||
void acomp_enable(uint8_t idx);
|
||||
void acomp_disable(uint8_t idx);
|
||||
void acomp_interrupt_mask(uint8_t idx,uint32_t flag);
|
||||
void acomp_interrupt_unmask(uint8_t idx,uint32_t flag);
|
||||
int acomp_get_result(uint8_t idx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,112 +0,0 @@
|
||||
/**
|
||||
* @file hal_cam.h
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __HAL_CAM_H__
|
||||
#define __HAL_CAM_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hal_common.h"
|
||||
#include "drv_device.h"
|
||||
#include "bl702_config.h"
|
||||
|
||||
#define DEVICE_CTRL_CAM_FRAME_CUT 0x10
|
||||
#define DEVICE_CTRL_CAM_FRAME_DROP 0x11
|
||||
#define DEVICE_CTRL_CAM_FRAME_WRAP 0x12
|
||||
|
||||
enum cam_index_type {
|
||||
#ifdef BSP_USING_CAM0
|
||||
CAM0_INDEX,
|
||||
#endif
|
||||
CAM_MAX_INDEX
|
||||
};
|
||||
|
||||
#define CAM_AUTO_MODE 0
|
||||
#define CAM_MANUAL_MODE 1
|
||||
|
||||
#define CAM_FRAME_PLANAR_MODE 0
|
||||
#define CAM_FRAME_INTERLEAVE_MODE 1
|
||||
|
||||
#define CAM_HSPOLARITY_LOW 0
|
||||
#define CAM_HSPOLARITY_HIGH 1
|
||||
|
||||
#define CAM_VSPOLARITY_LOW 0
|
||||
#define CAM_VSPOLARITY_HIGH 1
|
||||
|
||||
#define CAM_YUV_FORMAT_YUV422 0
|
||||
#define CAM_YUV_FORMAT_YUV420_EVEN 1
|
||||
#define CAM_YUV_FORMAT_YUV420_ODD 2
|
||||
#define CAM_YUV_FORMAT_YUV400_EVEN 3
|
||||
#define CAM_YUV_FORMAT_YUV400_ODD 4
|
||||
|
||||
enum cam_it_type {
|
||||
CAM_FRAME_IT = 1 << 0,
|
||||
};
|
||||
|
||||
enum cam_event_type {
|
||||
CAM_EVENT_FRAME = 0,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int16_t x0;
|
||||
int16_t x1;
|
||||
int16_t y0;
|
||||
int16_t y1;
|
||||
} cam_frame_area_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t frame_addr;
|
||||
uint32_t frame_count;
|
||||
} cam_frame_info_t;
|
||||
|
||||
typedef struct cam_device {
|
||||
struct device parent;
|
||||
uint8_t id;
|
||||
uint8_t software_mode;
|
||||
uint8_t frame_mode;
|
||||
uint8_t yuv_format;
|
||||
uint8_t hsp;
|
||||
uint8_t vsp;
|
||||
uint32_t cam_write_ram_addr;
|
||||
uint32_t cam_write_ram_size;
|
||||
uint32_t cam_frame_size;
|
||||
|
||||
// planar mode need use:
|
||||
uint32_t cam_write_ram_addr1;
|
||||
uint32_t cam_write_ram_size1;
|
||||
uint32_t cam_frame_size1;
|
||||
} cam_device_t;
|
||||
|
||||
#define CAM_DEV(dev) ((cam_device_t *)dev)
|
||||
|
||||
int cam_register(enum cam_index_type index, const char *name);
|
||||
void cam_drop_one_frame_interleave(void);
|
||||
uint8_t cam_get_one_frame_interleave(uint8_t **pic, uint32_t *len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,72 +0,0 @@
|
||||
/**
|
||||
* @file hal_dac.h
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef __HAL_DAC__H__
|
||||
#define __HAL_DAC__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hal_common.h"
|
||||
#include "drv_device.h"
|
||||
#include "bl702_config.h"
|
||||
|
||||
enum dac_index_type {
|
||||
#ifdef BSP_USING_DAC0
|
||||
DAC0_INDEX,
|
||||
#endif
|
||||
DAC_MAX_INDEX
|
||||
};
|
||||
|
||||
#define DAC_CHANNEL_0 (1 << 0)
|
||||
#define DAC_CHANNEL_1 (1 << 1)
|
||||
#define DAC_CHANNEL_ALL (DAC_CHANNEL_0 | DAC_CHANNEL_1)
|
||||
|
||||
/* default a_rng and b_rng is 0x03*/
|
||||
/*output Voltage = (1.8V-0.2V) * digital_val/1024 + 0.2V */
|
||||
#define DAC_VREF_INTERNAL 0 /*0.2V~1.8V*/
|
||||
/*output Voltage = (0.9vref-0.1vref) * digital_val/1024 + 0.1vref */
|
||||
#define DAC_VREF_EXTERNAL 1 /*0.1vref~0.9vref,using gpio7 for GPIO_FUN_ADC*/
|
||||
|
||||
enum dac_sample_frequence {
|
||||
DAC_SAMPLE_FREQ_8KHZ,
|
||||
DAC_SAMPLE_FREQ_16KHZ,
|
||||
DAC_SAMPLE_FREQ_44P1KHZ,
|
||||
DAC_SAMPLE_FREQ_500KHZ,
|
||||
};
|
||||
|
||||
typedef struct dac_device {
|
||||
struct device parent;
|
||||
enum dac_sample_frequence sample_freq;
|
||||
uint8_t channels;
|
||||
uint8_t vref;
|
||||
void *tx_dma;
|
||||
} dac_device_t;
|
||||
|
||||
#define DAC_DEV(dev) ((adc_device_t *)dev)
|
||||
|
||||
int dac_register(enum dac_index_type index, const char *name);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,110 +0,0 @@
|
||||
/**
|
||||
* @file hal_emac.h
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __HAL_EMAC_H__
|
||||
#define __HAL_EMAC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include "hal_common.h"
|
||||
#include "drv_device.h"
|
||||
#include "bl702_config.h"
|
||||
#include "bl702_emac.h"
|
||||
|
||||
typedef struct emac_device {
|
||||
struct device parent;
|
||||
uint8_t mac_addr[6]; /*!< mac address */
|
||||
} emac_device_t;
|
||||
|
||||
/**
|
||||
* @brief EMAC PHY configuration type definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t auto_negotiation; /*!< Speed and mode auto negotiation */
|
||||
uint8_t full_duplex; /*!< Duplex mode */
|
||||
#define PHY_STATE_DOWN (0) /* PHY is not usable */
|
||||
#define PHY_STATE_READY (1) /* PHY is OK, wait for controller */
|
||||
#define PHY_STATE_UP (2) /* Network is ready for TX/RX */
|
||||
#define PHY_STATE_RUNNING (3) /* working */
|
||||
#define PHY_STATE_NOLINK (4) /* no cable connected */
|
||||
#define PHY_STATE_STOPPED (5) /* PHY has been stopped */
|
||||
#define PHY_STATE_TESTING (6) /* in test mode */
|
||||
uint8_t phy_state; /*!< down,ready,up,running,nolink,halted */
|
||||
uint16_t speed; /*!< Speed mode */
|
||||
uint16_t phy_address; /*!< PHY address */
|
||||
uint32_t phy_id; /*!< PHY OUI */
|
||||
} emac_phy_cfg_t;
|
||||
|
||||
#define FULL_PACKET (uint32_t)(-1)
|
||||
#define NOFULL_PACKET (uint32_t)(0)
|
||||
|
||||
#ifndef ETH_TX_BUFFER_SIZE
|
||||
#define ETH_TX_BUFFER_SIZE (ETH_MAX_PACKET_SIZE)
|
||||
#endif
|
||||
|
||||
#ifndef ETH_RX_BUFFER_SIZE
|
||||
#define ETH_RX_BUFFER_SIZE (ETH_MAX_PACKET_SIZE)
|
||||
#endif
|
||||
|
||||
#define EMAC_TX_COMMON_FLAGS (EMAC_BD_FIELD_MSK(TX_RD) | \
|
||||
EMAC_BD_FIELD_MSK(TX_IRQ) | \
|
||||
EMAC_BD_FIELD_MSK(TX_PAD) | \
|
||||
EMAC_BD_FIELD_MSK(TX_CRC))
|
||||
|
||||
#define EMAC_RX_COMMON_FLAGS (ETH_MAX_PACKET_SIZE << 16) | \
|
||||
EMAC_BD_FIELD_MSK(RX_IRQ) )
|
||||
|
||||
typedef enum _BD_TYPE_ {
|
||||
EMAC_BD_TYPE_INVLAID,
|
||||
EMAC_BD_TYPE_TX,
|
||||
EMAC_BD_TYPE_RX,
|
||||
EMAC_BD_TYPE_NONE,
|
||||
EMAC_BD_TYPE_MAX = 0x7FFFFFFF
|
||||
} EMAC_BD_TYPE_e;
|
||||
|
||||
int emac_init(emac_device_t *emac_cfg);
|
||||
int emac_bd_init(uint8_t *ethTxBuff, uint8_t txBufCount, uint8_t *ethRxBuff, uint8_t rxBufCount);
|
||||
int emac_bd_tx_enqueue(uint32_t flags, uint32_t len, const uint8_t *data_in);
|
||||
int emac_bd_rx_dequeue(uint32_t flags, uint32_t *len, uint8_t *data_out);
|
||||
__WEAK void emac_rx_done_callback_app(void);
|
||||
__WEAK void emac_rx_error_callback_app(void);
|
||||
__WEAK void emac_rx_busy_callback_app(void);
|
||||
__WEAK void emac_tx_error_callback_app(void);
|
||||
__WEAK void emac_tx_done_callback_app(void);
|
||||
int emac_phy_set_address(uint16_t phyAddress);
|
||||
int emac_phy_config_full_duplex(uint8_t fullDuplex);
|
||||
int emac_phy_reg_read(uint16_t phyReg, uint16_t *regValue);
|
||||
int emac_phy_reg_write(uint16_t phyReg, uint16_t regValue);
|
||||
int emac_stop(void);
|
||||
int emac_start(void);
|
||||
int emac_start_tx(void);
|
||||
int emac_stop_tx(void);
|
||||
int emac_start_rx(void);
|
||||
int emac_stop_rx(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,125 +0,0 @@
|
||||
/**
|
||||
* @file hal_i2s.h
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef __HAL_I2S__H__
|
||||
#define __HAL_I2S__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include "hal_common.h"
|
||||
#include "drv_device.h"
|
||||
#include "bl702_config.h"
|
||||
|
||||
#define DEVICE_CTRL_I2S_GET_TX_FIFO 0x10
|
||||
#define DEVICE_CTRL_I2S_GET_RX_FIFO 0x11
|
||||
|
||||
#define DEVICE_CTRL_I2S_SET_SAMPL_FREQ 0x12
|
||||
|
||||
enum i2s_index_type {
|
||||
#ifdef BSP_USING_I2S0
|
||||
I2S0_INDEX,
|
||||
#endif
|
||||
I2S_MAX_INDEX
|
||||
};
|
||||
|
||||
#define I2S_DEFAULT_RTO_TIMEOUT 15
|
||||
|
||||
/*!
|
||||
* @brief I2S mode type settings
|
||||
*
|
||||
* This enumeration defines the I2S mode type
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_MODE_STD, /*!< I2S STD Mode */
|
||||
I2S_MODE_LEFT, /*!< Left-Justified Mode */
|
||||
I2S_MODE_RIGHT, /*!< Right-Justified Mode */
|
||||
I2S_MODE_DSP_A, /*!< DSP/PCM Mode A*/
|
||||
I2S_MODE_DSP_B, /*!< DSP/PCM Mode B*/
|
||||
} interface_mode_t;
|
||||
|
||||
/*!
|
||||
* @brief I2S frame size settings
|
||||
*
|
||||
* This enumeration defines the frame size type
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_FRAME_LEN_8 = 1, /*!< I2S frame size 8 bits */
|
||||
I2S_FRAME_LEN_16 = 2, /*!< I2S frame size 16 bits */
|
||||
I2S_FRAME_LEN_24 = 3, /*!< I2S frame size 24 bits */
|
||||
I2S_FRAME_LEN_32 = 4, /*!< I2S frame size 32 bits */
|
||||
} i2s_frame_size_t;
|
||||
|
||||
/*!
|
||||
* @brief I2S data size settings
|
||||
*
|
||||
* This enumeration defines the data size type
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_DATA_LEN_8 = 1, /*!< I2S data size 8 bits */
|
||||
I2S_DATA_LEN_16 = 2, /*!< I2S data size 16 bits */
|
||||
I2S_DATA_LEN_24 = 3, /*!< I2S data size 24 bits */
|
||||
I2S_DATA_LEN_32 = 4, /*!< I2S data size 32 bits */
|
||||
} i2s_data_size_t;
|
||||
|
||||
/*!
|
||||
* @brief I2S frame channel settings
|
||||
*
|
||||
* This enumeration defines the frame channel mode type
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_FS_CHANNELS_NUM_MONO = 1, /*!< I2S frame is for 1 channels */
|
||||
I2S_FS_CHANNELS_NUM_2 = 2, /*!< I2S frame is for 2 channels */
|
||||
I2S_FS_CHANNELS_NUM_3 = 3, /*!< I2S frame is for 3 channels, DSP mode only, frame_size must equal data_size*/
|
||||
I2S_FS_CHANNELS_NUM_4 = 4, /*!< I2S frame is for 4 channels, DSP mode only, frame_size must equal data_size*/
|
||||
} i2s_channel_num_t;
|
||||
|
||||
typedef enum {
|
||||
I2S_MODE_MASTER = 0, /*!< I2S as master */
|
||||
I2S_MODE_SLAVE, /*!< I2S as slave */
|
||||
} i2s_mode_t;
|
||||
|
||||
typedef struct i2s_device {
|
||||
struct device parent;
|
||||
uint8_t id;
|
||||
|
||||
i2s_mode_t iis_mode;
|
||||
interface_mode_t interface_mode;
|
||||
uint32_t sampl_freq_hz; /*!< I2S sample data frequency in Hz */
|
||||
i2s_channel_num_t channel_num;
|
||||
i2s_frame_size_t frame_size;
|
||||
i2s_data_size_t data_size;
|
||||
uint8_t fifo_threshold; /*!< I2S receive and transmit threshold*/
|
||||
void *tx_dma;
|
||||
void *rx_dma;
|
||||
} i2s_device_t;
|
||||
|
||||
#define I2S_DEV(dev) ((i2s_device_t *)dev)
|
||||
|
||||
int i2s_register(enum i2s_index_type index, const char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,97 +0,0 @@
|
||||
/**
|
||||
* @file hal_keyscan.h
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef __HAL_KEYSCAN__H__
|
||||
#define __HAL_KEYSCAN__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include "hal_common.h"
|
||||
#include "drv_device.h"
|
||||
#include "bl702_config.h"
|
||||
|
||||
#define DEVICE_CTRL_KEYSCAN_GET_KEYCODE 0x10
|
||||
|
||||
enum keyscan_index_type {
|
||||
#ifdef BSP_USING_KEYSCAN
|
||||
KEYSCAN_INDEX,
|
||||
#endif
|
||||
KEYSCAN_MAX_INDEX
|
||||
};
|
||||
|
||||
enum col_num_type {
|
||||
COL_NUM_1 = 1,
|
||||
COL_NUM_2,
|
||||
COL_NUM_3,
|
||||
COL_NUM_4,
|
||||
COL_NUM_5,
|
||||
COL_NUM_6,
|
||||
COL_NUM_7,
|
||||
COL_NUM_8,
|
||||
COL_NUM_9,
|
||||
COL_NUM_10,
|
||||
COL_NUM_11,
|
||||
COL_NUM_12,
|
||||
COL_NUM_13,
|
||||
COL_NUM_14,
|
||||
COL_NUM_15,
|
||||
COL_NUM_16,
|
||||
COL_NUM_17,
|
||||
COL_NUM_18,
|
||||
COL_NUM_19,
|
||||
COL_NUM_20
|
||||
};
|
||||
|
||||
enum row_num_type {
|
||||
ROW_NUM_1 = 1,
|
||||
ROW_NUM_2,
|
||||
ROW_NUM_3,
|
||||
ROW_NUM_4,
|
||||
ROW_NUM_5,
|
||||
ROW_NUM_6,
|
||||
ROW_NUM_7,
|
||||
ROW_NUM_8,
|
||||
};
|
||||
|
||||
enum keyscan_event_type {
|
||||
KEYSCAN_EVENT_TRIG,
|
||||
KEYSCAN_EVENT_UNKNOWN
|
||||
};
|
||||
|
||||
typedef struct keyscan_device {
|
||||
struct device parent;
|
||||
enum col_num_type col_num;
|
||||
enum row_num_type row_num;
|
||||
uint8_t deglitch_count;
|
||||
|
||||
} keyscan_device_t;
|
||||
|
||||
#define KEYSCAN_DEV(dev) ((keyscan_device_t *)dev)
|
||||
|
||||
int keyscan_register(enum keyscan_index_type index, const char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,77 +0,0 @@
|
||||
/**
|
||||
* @file hal_mjpeg.h
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef __HAL_MJPEG__H__
|
||||
#define __HAL_MJPEG__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include "hal_common.h"
|
||||
#include "drv_device.h"
|
||||
#include "bl702_config.h"
|
||||
|
||||
#define MJPEG_PACKET_ADD_NONE 0
|
||||
#define MJPEG_PACKET_ADD_DEFAULT 1 << 0
|
||||
#define MJPEG_PACKET_ADD_FRAME_HEAD 1 << 1
|
||||
#define MJPEG_PACKET_ADD_FRAME_TAIL 1 << 2
|
||||
#define MJPEG_PACKET_ADD_END_TAIL 1 << 3
|
||||
|
||||
/**
|
||||
* @brief MJPEG YUV format definition
|
||||
*/
|
||||
typedef enum {
|
||||
MJPEG_YUV_FORMAT_YUV420, /*!< MJPEG YUV420 planar mode */
|
||||
MJPEG_YUV_FORMAT_YUV400, /*!< MJPEG YUV400 grey scale mode */
|
||||
MJPEG_YUV_FORMAT_YUV422_PLANAR, /*!< MJPEG YUV422 planar mode */
|
||||
MJPEG_YUV_FORMAT_YUV422_INTERLEAVE, /*!< MJPEG YUV422 interleave mode */
|
||||
} mjpeg_yuv_format_t;
|
||||
|
||||
typedef struct mjpeg_device {
|
||||
struct device parent;
|
||||
uint8_t quality;
|
||||
mjpeg_yuv_format_t yuv_format;
|
||||
uint32_t write_buffer_addr; /*!< MJPEG buffer addr */
|
||||
uint32_t write_buffer_size; /*!< MJPEG buffer size */
|
||||
uint32_t read_buffer_addr;
|
||||
uint32_t read_buffer_size;
|
||||
uint16_t resolution_x; /*!< CAM RESOLUTION X */
|
||||
uint16_t resolution_y; /*!< CAM RESOLUTION Y */
|
||||
|
||||
uint8_t packet_cut_mode;
|
||||
uint16_t frame_head_length;
|
||||
uint16_t packet_head_length;
|
||||
uint16_t packet_body_length;
|
||||
uint16_t packet_tail_length;
|
||||
} mjpeg_device_t;
|
||||
|
||||
void mjpeg_init(mjpeg_device_t *mjpeg_cfg);
|
||||
void mjpeg_start(void);
|
||||
void mjpeg_stop(void);
|
||||
uint8_t mjpeg_get_one_frame(uint8_t **pic, uint32_t *len, uint8_t *q);
|
||||
void mjpeg_drop_one_frame(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,83 +0,0 @@
|
||||
/**
|
||||
* @file hal_qdec.h
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __HAL_QDEC__H__
|
||||
#define __HAL_QDEC__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include "hal_common.h"
|
||||
#include "drv_device.h"
|
||||
#include "bl702_config.h"
|
||||
|
||||
#define DEVICE_CTRL_GET_SAMPLE_VAL (0x10)
|
||||
#define DEVICE_CTRL_GET_SAMPLE_DIR (0x11)
|
||||
#define DEVICE_CTRL_GET_ERROR_CNT (0x12)
|
||||
|
||||
enum qdec_index_type {
|
||||
#ifdef BSP_USING_QDEC0
|
||||
QDEC0_INDEX,
|
||||
#endif
|
||||
#ifdef BSP_USING_QDEC1
|
||||
QDEC1_INDEX,
|
||||
#endif
|
||||
#ifdef BSP_USING_QDEC2
|
||||
QDEC2_INDEX,
|
||||
#endif
|
||||
QDEC_MAX_INDEX,
|
||||
};
|
||||
|
||||
enum qdec_event_type {
|
||||
QDEC_REPORT_EVENT = 1 << 0, /*!< report interrupt */
|
||||
QDEC_SAMPLE_EVENT = 1 << 1, /*!< sample interrupt */
|
||||
QDEC_ERROR_EVENT = 1 << 2, /*!< error interrupt */
|
||||
QDEC_OVERFLOW_EVENT = 1 << 3, /*!< ACC1 and ACC2 overflow interrupt */
|
||||
QDEC_ALL_EVENT = 1 << 4, /*!< interrupt max num */
|
||||
};
|
||||
|
||||
typedef struct qdec_device {
|
||||
struct device parent;
|
||||
uint8_t id;
|
||||
|
||||
uint8_t acc_mode;
|
||||
uint8_t sample_mode;
|
||||
uint8_t sample_period;
|
||||
uint8_t report_mode;
|
||||
uint32_t report_period;
|
||||
uint8_t led_en;
|
||||
uint8_t led_swap;
|
||||
uint16_t led_period;
|
||||
uint8_t deglitch_en;
|
||||
uint8_t deglitch_strength;
|
||||
|
||||
} qdec_device_t;
|
||||
|
||||
#define QDEC_DEV(dev) ((qdec_device_t *)dev)
|
||||
|
||||
int qdec_register(enum qdec_index_type index, const char *name);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // __HAL_QDEC_H__
|
||||
@@ -1,123 +0,0 @@
|
||||
/**
|
||||
* @file hal_spi.h
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef __HAL_SPI__H__
|
||||
#define __HAL_SPI__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hal_common.h"
|
||||
#include "drv_device.h"
|
||||
#include "bl702_config.h"
|
||||
|
||||
#define SPI_FIFO_LEN 4
|
||||
|
||||
#define DEVICE_CTRL_SPI_CONFIG_CLOCK 0x10
|
||||
|
||||
#define DEVICE_CTRL_SPI_GET_TX_FIFO 0x11
|
||||
#define DEVICE_CTRL_SPI_GET_RX_FIFO 0x12
|
||||
#define DEVICE_CTRL_SPI_CLEAR_TX_FIFO 0x13
|
||||
#define DEVICE_CTRL_SPI_CLEAR_RX_FIFO 0x14
|
||||
|
||||
#define DEVICE_CTRL_SPI_GET_BUS_BUSY_STATUS 0x15
|
||||
|
||||
enum spi_index_type {
|
||||
#ifdef BSP_USING_SPI0
|
||||
SPI0_INDEX,
|
||||
#endif
|
||||
SPI_MAX_INDEX
|
||||
};
|
||||
|
||||
/** @defgroup SPI_Direction SPI Direction Mode
|
||||
* @{
|
||||
*/
|
||||
#define SPI_LSB_BYTE0_DIRECTION_FIRST 0
|
||||
#define SPI_LSB_BYTE3_DIRECTION_FIRST 1
|
||||
#define SPI_MSB_BYTE0_DIRECTION_FIRST 2
|
||||
#define SPI_MSB_BYTE3_DIRECTION_FIRST 3
|
||||
|
||||
/** @defgroup SPI_Data_Size SPI Data Size
|
||||
* @{
|
||||
*/
|
||||
#define SPI_DATASIZE_8BIT 0
|
||||
#define SPI_DATASIZE_16BIT 1
|
||||
#define SPI_DATASIZE_24BIT 2
|
||||
#define SPI_DATASIZE_32BIT 3
|
||||
|
||||
/** @defgroup SPI_Clock_Polarity SPI Clock Polarity
|
||||
* @{
|
||||
*/
|
||||
#define SPI_POLARITY_LOW 0
|
||||
#define SPI_POLARITY_HIGH 1
|
||||
|
||||
/** @defgroup SPI_Clock_Phase SPI Clock Phase
|
||||
* @{
|
||||
*/
|
||||
#define SPI_PHASE_1EDGE 0
|
||||
#define SPI_PHASE_2EDGE 1
|
||||
|
||||
/** @defgroup
|
||||
* @{
|
||||
*/
|
||||
#define SPI_SLVAE_MODE 0
|
||||
#define SPI_MASTER_MODE 1
|
||||
|
||||
#define SPI_TRANSFER_TYPE_8BIT 0
|
||||
#define SPI_TRANSFER_TYPE_16BIT 1
|
||||
#define SPI_TRANSFER_TPYE_24BIT 2
|
||||
#define SPI_TRANSFER_TYPE_32BIT 3
|
||||
|
||||
enum spi_event_type {
|
||||
SPI_EVENT_TX_FIFO,
|
||||
SPI_EVENT_RX_FIFO,
|
||||
SPI_EVENT_UNKNOWN
|
||||
};
|
||||
|
||||
typedef struct spi_device {
|
||||
struct device parent;
|
||||
uint8_t id;
|
||||
uint32_t clk;
|
||||
uint8_t mode;
|
||||
uint8_t direction;
|
||||
uint8_t clk_polaraity;
|
||||
uint8_t clk_phase;
|
||||
uint8_t datasize;
|
||||
uint8_t fifo_threshold;
|
||||
uint8_t pin_swap_enable; /*swap mosi and miso*/
|
||||
uint8_t delitch_cnt;
|
||||
void *tx_dma;
|
||||
void *rx_dma;
|
||||
} spi_device_t;
|
||||
|
||||
#define SPI_DEV(dev) ((spi_device_t *)dev)
|
||||
|
||||
int spi_register(enum spi_index_type index, const char *name);
|
||||
|
||||
int spi_transmit(struct device *dev, void *buffer, uint32_t size, uint8_t type);
|
||||
int spi_receive(struct device *dev, void *buffer, uint32_t size, uint8_t type);
|
||||
int spi_transmit_receive(struct device *dev, const void *send_buf, void *recv_buf, uint32_t length, uint8_t type);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,146 +0,0 @@
|
||||
#include "hal_acomp.h"
|
||||
#include "bl702_acomp.h"
|
||||
#include "hbn_reg.h"
|
||||
|
||||
void acomp_init(uint8_t idx, acomp_device_t *device)
|
||||
{
|
||||
uint32_t tmpVal;
|
||||
|
||||
if (idx == 0) {
|
||||
tmpVal = BL_RD_REG(HBN_BASE, HBN_IRQ_MODE);
|
||||
tmpVal &= ~(1 << 20);
|
||||
tmpVal &= ~(1 << 21);
|
||||
BL_WR_REG(HBN_BASE, HBN_IRQ_MODE, tmpVal);
|
||||
|
||||
/* Disable ACOMP first */
|
||||
tmpVal = BL_RD_REG(AON_BASE, AON_ACOMP0_CTRL);
|
||||
tmpVal = BL_CLR_REG_BIT(tmpVal, AON_ACOMP0_EN);
|
||||
tmpVal = BL_WR_REG(AON_BASE, AON_ACOMP0_CTRL, tmpVal);
|
||||
|
||||
/* Set ACOMP config */
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, AON_ACOMP0_MUXEN, 1);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, AON_ACOMP0_POS_SEL, device->pos_ch);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, AON_ACOMP0_NEG_SEL, device->neg_ch);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, AON_ACOMP0_LEVEL_SEL, AON_ACOMP_LEVEL_FACTOR_1);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, AON_ACOMP0_BIAS_PROG, AON_ACOMP_BIAS_POWER_MODE1);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, AON_ACOMP0_HYST_SELP, device->pos_hysteresis_vol);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, AON_ACOMP0_HYST_SELN, device->neg_hysteresis_vol);
|
||||
BL_WR_REG(AON_BASE, AON_ACOMP0_CTRL, tmpVal);
|
||||
|
||||
} else {
|
||||
tmpVal = BL_RD_REG(HBN_BASE, HBN_IRQ_MODE);
|
||||
tmpVal &= ~(1 << 22);
|
||||
tmpVal &= ~(1 << 23);
|
||||
BL_WR_REG(HBN_BASE, HBN_IRQ_MODE, tmpVal);
|
||||
|
||||
/* Disable ACOMP first */
|
||||
tmpVal = BL_RD_REG(AON_BASE, AON_ACOMP1_CTRL);
|
||||
tmpVal = BL_CLR_REG_BIT(tmpVal, AON_ACOMP1_EN);
|
||||
tmpVal = BL_WR_REG(AON_BASE, AON_ACOMP1_CTRL, tmpVal);
|
||||
|
||||
/* Set ACOMP config */
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, AON_ACOMP1_MUXEN, 1);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, AON_ACOMP1_POS_SEL, device->pos_ch);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, AON_ACOMP1_NEG_SEL, device->neg_ch);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, AON_ACOMP1_LEVEL_SEL, AON_ACOMP_LEVEL_FACTOR_1);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, AON_ACOMP1_BIAS_PROG, AON_ACOMP_BIAS_POWER_MODE1);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, AON_ACOMP1_HYST_SELP, device->pos_hysteresis_vol);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, AON_ACOMP1_HYST_SELN, device->neg_hysteresis_vol);
|
||||
BL_WR_REG(AON_BASE, AON_ACOMP1_CTRL, tmpVal);
|
||||
}
|
||||
}
|
||||
|
||||
void acomp_enable(uint8_t idx)
|
||||
{
|
||||
uint32_t tmpVal;
|
||||
if (idx == 0) {
|
||||
tmpVal = BL_RD_REG(AON_BASE, AON_ACOMP0_CTRL);
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, AON_ACOMP0_EN);
|
||||
BL_WR_REG(AON_BASE, AON_ACOMP0_CTRL, tmpVal);
|
||||
} else {
|
||||
tmpVal = BL_RD_REG(AON_BASE, AON_ACOMP1_CTRL);
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, AON_ACOMP1_EN);
|
||||
BL_WR_REG(AON_BASE, AON_ACOMP1_CTRL, tmpVal);
|
||||
}
|
||||
}
|
||||
|
||||
void acomp_disable(uint8_t idx)
|
||||
{
|
||||
uint32_t tmpVal;
|
||||
if (idx == 0) {
|
||||
tmpVal = BL_RD_REG(AON_BASE, AON_ACOMP0_CTRL);
|
||||
tmpVal = BL_CLR_REG_BIT(tmpVal, AON_ACOMP0_EN);
|
||||
BL_WR_REG(AON_BASE, AON_ACOMP0_CTRL, tmpVal);
|
||||
} else {
|
||||
tmpVal = BL_RD_REG(AON_BASE, AON_ACOMP1_CTRL);
|
||||
tmpVal = BL_CLR_REG_BIT(tmpVal, AON_ACOMP1_EN);
|
||||
BL_WR_REG(AON_BASE, AON_ACOMP1_CTRL, tmpVal);
|
||||
}
|
||||
}
|
||||
|
||||
void acomp_interrupt_mask(uint8_t idx, uint32_t flag)
|
||||
{
|
||||
uint32_t tmpVal;
|
||||
tmpVal = BL_RD_REG(HBN_BASE, HBN_IRQ_MODE);
|
||||
if (idx == 0) {
|
||||
tmpVal &= ~(flag << 20);
|
||||
} else {
|
||||
tmpVal &= ~(flag << 22);
|
||||
}
|
||||
}
|
||||
|
||||
void acomp_interrupt_unmask(uint8_t idx, uint32_t flag)
|
||||
{
|
||||
uint32_t tmpVal;
|
||||
|
||||
if (idx == 0) {
|
||||
/* set clear bit */
|
||||
tmpVal = BL_RD_REG(HBN_BASE, HBN_IRQ_CLR);
|
||||
tmpVal |= (1 << 20);
|
||||
BL_WR_REG(HBN_BASE, HBN_IRQ_CLR, tmpVal);
|
||||
|
||||
/* unset clear bit */
|
||||
tmpVal = BL_RD_REG(HBN_BASE, HBN_IRQ_CLR);
|
||||
tmpVal &= (~(1 << 20));
|
||||
BL_WR_REG(HBN_BASE, HBN_IRQ_CLR, tmpVal);
|
||||
|
||||
tmpVal = BL_RD_REG(HBN_BASE, HBN_IRQ_MODE);
|
||||
tmpVal |= (flag << 20);
|
||||
} else {
|
||||
/* set clear bit */
|
||||
tmpVal = BL_RD_REG(HBN_BASE, HBN_IRQ_CLR);
|
||||
tmpVal |= (1 << 22);
|
||||
BL_WR_REG(HBN_BASE, HBN_IRQ_CLR, tmpVal);
|
||||
|
||||
/* unset clear bit */
|
||||
tmpVal = BL_RD_REG(HBN_BASE, HBN_IRQ_CLR);
|
||||
tmpVal &= (~(1 << 22));
|
||||
BL_WR_REG(HBN_BASE, HBN_IRQ_CLR, tmpVal);
|
||||
|
||||
tmpVal = BL_RD_REG(HBN_BASE, HBN_IRQ_MODE);
|
||||
tmpVal |= (flag << 22);
|
||||
}
|
||||
|
||||
BL_WR_REG(HBN_BASE, HBN_IRQ_MODE, tmpVal);
|
||||
}
|
||||
|
||||
int acomp_get_result(uint8_t idx)
|
||||
{
|
||||
uint32_t tmpVal;
|
||||
tmpVal = BL_RD_REG(AON_BASE, AON_ACOMP_CTRL);
|
||||
|
||||
/* Disable ACOMP first */
|
||||
if (idx == 0) {
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, AON_ACOMP0_OUT_RAW)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, AON_ACOMP1_OUT_RAW)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,342 +0,0 @@
|
||||
/**
|
||||
* @file hal_cam.c
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
#include "hal_cam.h"
|
||||
#include "bl702_cam.h"
|
||||
#include "bl702_glb.h"
|
||||
|
||||
#ifdef BSP_USING_CAM0
|
||||
static void CAM0_IRQ(void);
|
||||
#endif
|
||||
|
||||
static cam_device_t camx_device[CAM_MAX_INDEX] = {
|
||||
#ifdef BSP_USING_CAM0
|
||||
CAM0_CONFIG,
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @param oflag
|
||||
* @return int
|
||||
*/
|
||||
int cam_open(struct device *dev, uint16_t oflag)
|
||||
{
|
||||
cam_device_t *cam_device = (cam_device_t *)dev;
|
||||
CAM_CFG_Type camera_cfg = { 0 };
|
||||
|
||||
uint32_t tmpVal;
|
||||
/* Disable camera module */
|
||||
tmpVal = BL_RD_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE);
|
||||
tmpVal = BL_CLR_REG_BIT(tmpVal, CAM_REG_DVP_ENABLE);
|
||||
BL_WR_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE, tmpVal);
|
||||
|
||||
camera_cfg.swMode = cam_device->software_mode;
|
||||
camera_cfg.frameMode = cam_device->frame_mode;
|
||||
camera_cfg.yuvMode = cam_device->yuv_format;
|
||||
camera_cfg.waitCount = 0x40;
|
||||
camera_cfg.linePol = cam_device->hsp;
|
||||
camera_cfg.framePol = cam_device->vsp;
|
||||
camera_cfg.burstType = CAM_BURST_TYPE_INCR16;
|
||||
camera_cfg.camSensorMode = CAM_SENSOR_MODE_V_AND_H;
|
||||
camera_cfg.memStart0 = cam_device->cam_write_ram_addr;
|
||||
camera_cfg.memSize0 = cam_device->cam_write_ram_size;
|
||||
camera_cfg.frameSize0 = cam_device->cam_frame_size;
|
||||
/* planar mode*/
|
||||
camera_cfg.memStart1 = cam_device->cam_write_ram_addr1;
|
||||
camera_cfg.memSize1 = cam_device->cam_write_ram_size1;
|
||||
camera_cfg.frameSize1 = cam_device->cam_frame_size1;
|
||||
CAM_Init(&camera_cfg);
|
||||
|
||||
if (oflag & DEVICE_OFLAG_INT_RX) {
|
||||
#ifdef BSP_USING_CAM0
|
||||
Interrupt_Handler_Register(CAM_IRQn, CAM0_IRQ);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @return int
|
||||
*/
|
||||
int cam_close(struct device *dev)
|
||||
{
|
||||
GLB_AHB_Slave1_Reset(BL_AHB_SLAVE1_CAM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @param cmd
|
||||
* @param args
|
||||
* @return int
|
||||
*/
|
||||
int cam_control(struct device *dev, int cmd, void *args)
|
||||
{
|
||||
cam_device_t *cam_device = (cam_device_t *)dev;
|
||||
|
||||
switch (cmd) {
|
||||
case DEVICE_CTRL_SET_INT:
|
||||
if ((uint32_t)args == CAM_FRAME_IT) {
|
||||
CAM_IntMask(CAM_INT_NORMAL_0, UNMASK);
|
||||
CPU_Interrupt_Enable(CAM_IRQn);
|
||||
}
|
||||
|
||||
break;
|
||||
case DEVICE_CTRL_CLR_INT:
|
||||
if ((uint32_t)args == CAM_FRAME_IT) {
|
||||
CAM_IntMask(CAM_INT_NORMAL_0, MASK);
|
||||
CPU_Interrupt_Disable(CAM_IRQn);
|
||||
}
|
||||
break;
|
||||
case DEVICE_CTRL_RESUME: {
|
||||
uint32_t tmpVal;
|
||||
|
||||
/* Enable camera module */
|
||||
tmpVal = BL_RD_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE);
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, CAM_REG_DVP_ENABLE);
|
||||
BL_WR_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE, tmpVal);
|
||||
} break;
|
||||
case DEVICE_CTRL_SUSPEND: {
|
||||
uint32_t tmpVal;
|
||||
|
||||
/* Disable camera module */
|
||||
tmpVal = BL_RD_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE);
|
||||
tmpVal = BL_CLR_REG_BIT(tmpVal, CAM_REG_DVP_ENABLE);
|
||||
BL_WR_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE, tmpVal);
|
||||
} break;
|
||||
case DEVICE_CTRL_CAM_FRAME_CUT: {
|
||||
cam_frame_area_t *cfg = (cam_frame_area_t *)args;
|
||||
BL_WR_REG(CAM_BASE, CAM_HSYNC_CONTROL, ((cfg->x0 * 2) << 16) + (cfg->x1 * 2));
|
||||
BL_WR_REG(CAM_BASE, CAM_VSYNC_CONTROL, ((cfg->y0) << 16) + cfg->y1);
|
||||
|
||||
} break;
|
||||
case DEVICE_CTRL_CAM_FRAME_DROP:
|
||||
if (cam_device->frame_mode == CAM_FRAME_INTERLEAVE_MODE) {
|
||||
/* Pop one frame */
|
||||
BL_WR_REG(CAM_BASE, CAM_DVP_FRAME_FIFO_POP, 1);
|
||||
} else {
|
||||
/* Pop one frame */
|
||||
BL_WR_REG(CAM_BASE, CAM_DVP_FRAME_FIFO_POP, 3);
|
||||
}
|
||||
break;
|
||||
case DEVICE_CTRL_CAM_FRAME_WRAP: {
|
||||
uint32_t tmpVal;
|
||||
|
||||
tmpVal = BL_RD_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CAM_REG_HW_MODE_FWRAP, ((uint32_t)args) & 0x01);
|
||||
BL_WR_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE, tmpVal);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @param pos
|
||||
* @param buffer
|
||||
* @param size
|
||||
* @return int
|
||||
*/
|
||||
int cam_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size)
|
||||
{
|
||||
if (!BL_GET_REG_BITS_VAL(BL_RD_REG(CAM_BASE, CAM_DVP_STATUS_AND_ERROR), CAM_FRAME_VALID_CNT_0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cam_frame_info_t *frame_info = (cam_frame_info_t *)buffer;
|
||||
|
||||
frame_info->frame_addr = BL_RD_REG(CAM_BASE, CAM_FRAME_START_ADDR0_0);
|
||||
frame_info->frame_count = BL_RD_REG(CAM_BASE, CAM_FRAME_BYTE_CNT0_0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param index
|
||||
* @param name
|
||||
* @return int
|
||||
*/
|
||||
int cam_register(enum cam_index_type index, const char *name)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
if (CAM_MAX_INDEX == 0) {
|
||||
return -DEVICE_EINVAL;
|
||||
}
|
||||
|
||||
dev = &(camx_device[index].parent);
|
||||
|
||||
dev->open = cam_open;
|
||||
dev->close = cam_close;
|
||||
dev->control = cam_control;
|
||||
dev->write = NULL;
|
||||
dev->read = cam_read;
|
||||
|
||||
dev->type = DEVICE_CLASS_CAMERA;
|
||||
dev->handle = NULL;
|
||||
|
||||
return device_register(dev, name);
|
||||
}
|
||||
|
||||
void cam_isr(cam_device_t *handle)
|
||||
{
|
||||
uint32_t tmpVal;
|
||||
|
||||
if (!handle->parent.callback)
|
||||
return;
|
||||
|
||||
tmpVal = BL_RD_REG(CAM_BASE, CAM_DVP_STATUS_AND_ERROR);
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_NORMAL_INT_0)) {
|
||||
CAM_IntClr(CAM_INT_NORMAL_0);
|
||||
handle->parent.callback(&handle->parent, NULL, 0, CAM_EVENT_FRAME);
|
||||
}
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_NORMAL_INT_1)) {
|
||||
CAM_IntClr(CAM_INT_NORMAL_1);
|
||||
}
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_MEM_INT_0)) {
|
||||
CAM_IntClr(CAM_INT_MEMORY_OVERWRITE_0);
|
||||
}
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_MEM_INT_1)) {
|
||||
CAM_IntClr(CAM_INT_MEMORY_OVERWRITE_1);
|
||||
}
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_FRAME_INT_0)) {
|
||||
CAM_IntClr(CAM_INT_FRAME_OVERWRITE_0);
|
||||
}
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_FRAME_INT_1)) {
|
||||
CAM_IntClr(CAM_INT_FRAME_OVERWRITE_1);
|
||||
}
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_FIFO_INT_0)) {
|
||||
CAM_IntClr(CAM_INT_FIFO_OVERWRITE_0);
|
||||
}
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_FIFO_INT_1)) {
|
||||
CAM_IntClr(CAM_INT_FIFO_OVERWRITE_1);
|
||||
}
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_HCNT_INT)) {
|
||||
CAM_IntClr(CAM_INT_HSYNC_CNT_ERROR);
|
||||
}
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_VCNT_INT)) {
|
||||
CAM_IntClr(CAM_INT_VSYNC_CNT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BSP_USING_CAM0
|
||||
void CAM0_IRQ(void)
|
||||
{
|
||||
cam_isr(&camx_device[CAM0_INDEX]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
void cam_start(void)
|
||||
{
|
||||
uint32_t tmpVal;
|
||||
|
||||
/* Enable camera module */
|
||||
tmpVal = BL_RD_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE);
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, CAM_REG_DVP_ENABLE);
|
||||
BL_WR_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE, tmpVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
void cam_stop(void)
|
||||
{
|
||||
uint32_t tmpVal;
|
||||
|
||||
/* Disable camera module */
|
||||
tmpVal = BL_RD_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE);
|
||||
tmpVal = BL_CLR_REG_BIT(tmpVal, CAM_REG_DVP_ENABLE);
|
||||
BL_WR_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE, tmpVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param pic
|
||||
* @param len
|
||||
*/
|
||||
uint8_t cam_get_one_frame_interleave(uint8_t **pic, uint32_t *len)
|
||||
{
|
||||
if (!BL_GET_REG_BITS_VAL(BL_RD_REG(CAM_BASE, CAM_DVP_STATUS_AND_ERROR), CAM_FRAME_VALID_CNT_0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*pic = (uint8_t *)BL_RD_REG(CAM_BASE, CAM_FRAME_START_ADDR0_0);
|
||||
*len = BL_RD_REG(CAM_BASE, CAM_FRAME_BYTE_CNT0_0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t cam_get_one_frame_planar(CAM_YUV_Mode_Type yuv, uint8_t **picYY, uint32_t *lenYY, uint8_t **picUV, uint32_t *lenUV)
|
||||
{
|
||||
CAM_Planar_Frame_Info info;
|
||||
arch_memset(&info, 0, sizeof(info));
|
||||
|
||||
CAM_Planar_Get_Frame_Info(&info);
|
||||
|
||||
if (yuv == CAM_YUV400_EVEN || yuv == CAM_YUV400_ODD) {
|
||||
if (info.validFrames0 == 0 && info.validFrames1 == 0) {
|
||||
return ERROR;
|
||||
}
|
||||
} else {
|
||||
if (info.validFrames0 == 0 || info.validFrames1 == 0) {
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
*picYY = (uint8_t *)(info.curFrameAddr0);
|
||||
*lenYY = info.curFrameBytes0;
|
||||
*picUV = (uint8_t *)(info.curFrameAddr1);
|
||||
*lenUV = info.curFrameBytes1;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void cam_drop_one_frame_interleave(void)
|
||||
{
|
||||
/* Pop one frame */
|
||||
BL_WR_REG(CAM_BASE, CAM_DVP_FRAME_FIFO_POP, 1);
|
||||
}
|
||||
|
||||
void cam_drop_one_frame_planar(void)
|
||||
{
|
||||
/* Pop one frame */
|
||||
BL_WR_REG(CAM_BASE, CAM_DVP_FRAME_FIFO_POP, 3);
|
||||
}
|
||||
@@ -1,329 +0,0 @@
|
||||
/**
|
||||
* @file hal_dac.c
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
#include "hal_dac.h"
|
||||
#include "hal_dma.h"
|
||||
#include "hal_clock.h"
|
||||
#include "bl702_dac.h"
|
||||
#include "bl702_glb.h"
|
||||
|
||||
static dac_device_t dacx_device[] = {
|
||||
#ifdef BSP_USING_DAC0
|
||||
DAC_CONFIG,
|
||||
#endif
|
||||
};
|
||||
|
||||
static uint8_t dac_channel_enable_check = 0;
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @param oflag
|
||||
* @return int
|
||||
*/
|
||||
int dac_open(struct device *dev, uint16_t oflag)
|
||||
{
|
||||
dac_device_t *dac_device = (dac_device_t *)dev;
|
||||
uint8_t dac_div = 0;
|
||||
uint32_t tmpVal;
|
||||
|
||||
uint32_t dac_clk = peripheral_clock_get(PERIPHERAL_CLOCK_DAC);
|
||||
|
||||
if ((GLB_GPIO_Get_Fun(GLB_GPIO_PIN_11) == GPIO_FUN_ANALOG) && (dac_device->channels & DAC_CHANNEL_0)) {
|
||||
dac_channel_enable_check |= DAC_CHANNEL_0;
|
||||
}
|
||||
if ((GLB_GPIO_Get_Fun(GLB_GPIO_PIN_17) == GPIO_FUN_ANALOG) && (dac_device->channels & DAC_CHANNEL_1)) {
|
||||
dac_channel_enable_check |= DAC_CHANNEL_1;
|
||||
}
|
||||
|
||||
if (dac_channel_enable_check == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (dac_device->sample_freq) {
|
||||
case DAC_SAMPLE_FREQ_500KHZ:
|
||||
dac_div = dac_clk / 500000;
|
||||
break;
|
||||
|
||||
case DAC_SAMPLE_FREQ_8KHZ:
|
||||
dac_div = dac_clk / 8000;
|
||||
break;
|
||||
|
||||
case DAC_SAMPLE_FREQ_16KHZ:
|
||||
dac_div = dac_clk / 16000;
|
||||
break;
|
||||
|
||||
case DAC_SAMPLE_FREQ_44P1KHZ:
|
||||
dac_div = dac_clk / 441000;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (dac_div == 1) {
|
||||
dac_div = DAC_CLK_DIV_1;
|
||||
} else if (dac_div == 16) {
|
||||
dac_div = DAC_CLK_DIV_16;
|
||||
} else if (dac_div == 32) {
|
||||
dac_div = DAC_CLK_DIV_32;
|
||||
} else if (dac_div == 64) {
|
||||
dac_div = DAC_CLK_DIV_64;
|
||||
} else
|
||||
return -2;
|
||||
|
||||
tmpVal = BL_RD_REG(GLB_BASE, GLB_GPDAC_CTRL);
|
||||
/*dac vref select*/
|
||||
if (dac_device->vref == DAC_VREF_EXTERNAL) {
|
||||
if (GLB_GPIO_Get_Fun(GLB_GPIO_PIN_7) != GPIO_FUN_ANALOG)
|
||||
return -1;
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, GLB_GPDAC_REF_SEL);
|
||||
} else {
|
||||
tmpVal = BL_CLR_REG_BIT(tmpVal, GLB_GPDAC_REF_SEL);
|
||||
}
|
||||
BL_WR_REG(GLB_BASE, GLB_GPDAC_CTRL, tmpVal);
|
||||
|
||||
/*dac reset*/
|
||||
tmpVal = BL_CLR_REG_BIT(tmpVal, GLB_GPDACA_RSTN_ANA);
|
||||
BL_WR_REG(GLB_BASE, GLB_GPDAC_CTRL, tmpVal);
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
tmpVal = BL_CLR_REG_BIT(tmpVal, GLB_GPDACB_RSTN_ANA);
|
||||
BL_WR_REG(GLB_BASE, GLB_GPDAC_CTRL, tmpVal);
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
/* dac clear reset */
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, GLB_GPDACA_RSTN_ANA);
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, GLB_GPDACB_RSTN_ANA);
|
||||
BL_WR_REG(GLB_BASE, GLB_GPDAC_CTRL, tmpVal);
|
||||
|
||||
/* Set DAC div */
|
||||
tmpVal = BL_RD_REG(GPIP_BASE, GPIP_GPDAC_CONFIG);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GPIP_GPDAC_MODE, dac_div);
|
||||
BL_WR_REG(GPIP_BASE, GPIP_GPDAC_CONFIG, tmpVal);
|
||||
|
||||
/* select source */
|
||||
tmpVal = BL_RD_REG(GPIP_BASE, GPIP_GPDAC_CONFIG);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GPIP_GPDAC_CH_A_SEL, GPIP_DAC_ChanA_SRC_REG);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GPIP_GPDAC_CH_B_SEL, GPIP_DAC_ChanB_SRC_REG);
|
||||
BL_WR_REG(GPIP_BASE, GPIP_GPDAC_CONFIG, tmpVal);
|
||||
|
||||
/* GPIP enable or disable channel */
|
||||
tmpVal = BL_RD_REG(GPIP_BASE, GPIP_GPDAC_CONFIG);
|
||||
if (dac_channel_enable_check & DAC_CHANNEL_0) {
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, GPIP_GPDAC_EN);
|
||||
}
|
||||
if (dac_channel_enable_check & DAC_CHANNEL_1) {
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, GPIP_GPDAC_EN2);
|
||||
}
|
||||
BL_WR_REG(GPIP_BASE, GPIP_GPDAC_CONFIG, tmpVal);
|
||||
|
||||
/* GLB enable or disable channel */
|
||||
if (dac_channel_enable_check & DAC_CHANNEL_0) {
|
||||
/* a channel */
|
||||
tmpVal = BL_RD_REG(GLB_BASE, GLB_GPDAC_ACTRL);
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, GLB_GPDAC_IOA_EN);
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, GLB_GPDAC_A_EN);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_GPDAC_A_RNG, 0x03);
|
||||
tmpVal = BL_WR_REG(GLB_BASE, GLB_GPDAC_ACTRL, tmpVal);
|
||||
}
|
||||
if (dac_channel_enable_check & DAC_CHANNEL_1) {
|
||||
/* b channel */
|
||||
tmpVal = BL_RD_REG(GLB_BASE, GLB_GPDAC_BCTRL);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_GPDAC_B_RNG, 0x03);
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, GLB_GPDAC_IOB_EN);
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, GLB_GPDAC_B_EN);
|
||||
tmpVal = BL_WR_REG(GLB_BASE, GLB_GPDAC_BCTRL, tmpVal);
|
||||
}
|
||||
|
||||
/* GPIP disable DMA */
|
||||
tmpVal = BL_RD_REG(GPIP_BASE, GPIP_GPDAC_DMA_CONFIG);
|
||||
tmpVal = BL_CLR_REG_BIT(tmpVal, GPIP_GPDAC_DMA_TX_EN);
|
||||
BL_WR_REG(GPIP_BASE, GPIP_GPDAC_DMA_CONFIG, tmpVal);
|
||||
|
||||
if (oflag & DEVICE_OFLAG_DMA_TX) {
|
||||
/* GPIP select source */
|
||||
tmpVal = BL_RD_REG(GPIP_BASE, GPIP_GPDAC_CONFIG);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GPIP_GPDAC_CH_A_SEL, GPIP_DAC_ChanA_SRC_DMA);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GPIP_GPDAC_CH_B_SEL, GPIP_DAC_ChanB_SRC_DMA);
|
||||
BL_WR_REG(GPIP_BASE, GPIP_GPDAC_CONFIG, tmpVal);
|
||||
|
||||
/* GPIP enable DMA */
|
||||
tmpVal = BL_RD_REG(GPIP_BASE, GPIP_GPDAC_DMA_CONFIG);
|
||||
if (dac_channel_enable_check == 2) {
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GPIP_GPDAC_DMA_FORMAT, GPIP_DAC_DMA_FORMAT_1);
|
||||
} else {
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GPIP_GPDAC_DMA_FORMAT, GPIP_DAC_DMA_FORMAT_0);
|
||||
}
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, GPIP_GPDAC_DMA_TX_EN);
|
||||
BL_WR_REG(GPIP_BASE, GPIP_GPDAC_DMA_CONFIG, tmpVal);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @return int
|
||||
*/
|
||||
int dac_close(struct device *dev)
|
||||
{
|
||||
GLB_GPIP_DAC_ChanA_Cfg_Type chCfg = { 0 };
|
||||
GLB_GPIP_DAC_Cfg_Type dacCfg = { 0 };
|
||||
GLB_GPIP_DAC_Init(&dacCfg);
|
||||
GLB_GPIP_DAC_Set_ChanA_Config(&chCfg);
|
||||
GLB_GPIP_DAC_Set_ChanB_Config((GLB_GPIP_DAC_ChanB_Cfg_Type *)&chCfg);
|
||||
GPIP_Set_DAC_DMA_TX_Disable();
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @param cmd
|
||||
* @param args
|
||||
* @return int
|
||||
*/
|
||||
int dac_control(struct device *dev, int cmd, void *args)
|
||||
{
|
||||
dac_device_t *dac_device = (dac_device_t *)dev;
|
||||
|
||||
switch (cmd) {
|
||||
case DEVICE_CTRL_SET_INT:
|
||||
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_CLR_INT:
|
||||
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_GET_INT:
|
||||
/* code */
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_CONFIG:
|
||||
/* code */
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_RESUME:
|
||||
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_SUSPEND:
|
||||
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_ATTACH_TX_DMA:
|
||||
dac_device->tx_dma = (struct device *)args;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @param pos
|
||||
* @param buffer
|
||||
* @param size
|
||||
* @return int
|
||||
*/
|
||||
int dac_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
enum dac_sample_frequence channel = (enum dac_sample_frequence)pos;
|
||||
dac_device_t *dac_device = (dac_device_t *)dev;
|
||||
uint32_t i = 0;
|
||||
|
||||
if (dev->oflag & DEVICE_OFLAG_DMA_TX) {
|
||||
struct device *dma_ch = (struct device *)dac_device->tx_dma;
|
||||
|
||||
if (!dma_ch) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = dma_reload(dma_ch, (uint32_t)buffer, (uint32_t)DMA_ADDR_DAC_TDR, size);
|
||||
dma_channel_start(dma_ch);
|
||||
return ret;
|
||||
} else if (dev->oflag & DEVICE_OFLAG_STREAM_TX) {
|
||||
if ((channel & DAC_CHANNEL_ALL) == DAC_CHANNEL_ALL) {
|
||||
for (i = 0; i < size; i++) {
|
||||
GLB_DAC_Set_ChanA_Value(*((uint16_t *)buffer + i));
|
||||
GLB_DAC_Set_ChanB_Value(*((uint16_t *)buffer + i));
|
||||
}
|
||||
} else if (channel & DAC_CHANNEL_0) {
|
||||
for (i = 0; i < size; i++) {
|
||||
GLB_DAC_Set_ChanA_Value(*((uint16_t *)buffer + i));
|
||||
}
|
||||
} else if (channel & DAC_CHANNEL_1) {
|
||||
for (i = 0; i < size; i++) {
|
||||
GLB_DAC_Set_ChanB_Value(*((uint16_t *)buffer + i));
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param index
|
||||
* @param name
|
||||
* @return int
|
||||
*/
|
||||
int dac_register(enum dac_index_type index, const char *name)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
if (DAC_MAX_INDEX == 0) {
|
||||
return -DEVICE_EINVAL;
|
||||
}
|
||||
|
||||
dev = &(dacx_device[index].parent);
|
||||
|
||||
dev->open = dac_open;
|
||||
dev->close = dac_close;
|
||||
dev->control = dac_control;
|
||||
dev->write = dac_write;
|
||||
dev->read = NULL;
|
||||
|
||||
dev->type = DEVICE_CLASS_DAC;
|
||||
dev->handle = NULL;
|
||||
|
||||
device_register(dev, name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,569 +0,0 @@
|
||||
/**
|
||||
* @file hal_emac.c
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bl702_emac.h"
|
||||
#include "bl702_glb.h"
|
||||
#include "hal_emac.h"
|
||||
|
||||
#ifndef MSG
|
||||
#define MSG(a,...)
|
||||
#endif
|
||||
|
||||
#define EMAC_USE_INSIDE_CLOCK (0)
|
||||
#define TAG "EMAC_BD: "
|
||||
|
||||
static EMAC_Handle_Type ethHandle;
|
||||
static EMAC_Handle_Type *thiz = NULL;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
static void emac_gpio_init(void)
|
||||
{
|
||||
uint8_t emacPins[] = { GLB_GPIO_PIN_0, GLB_GPIO_PIN_1, GLB_GPIO_PIN_2,
|
||||
GLB_GPIO_PIN_7, GLB_GPIO_PIN_8,
|
||||
GLB_GPIO_PIN_18, GLB_GPIO_PIN_19, GLB_GPIO_PIN_20, GLB_GPIO_PIN_21, GLB_GPIO_PIN_22 };
|
||||
|
||||
GLB_SWAP_EMAC_CAM_Pin(GLB_EMAC_CAM_PIN_EMAC);
|
||||
|
||||
GLB_GPIO_Func_Init(GPIO_FUN_ETHER_MAC, (GLB_GPIO_Type *)emacPins, sizeof(emacPins));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param bdt
|
||||
* @return int
|
||||
*/
|
||||
static uint32_t emac_bd_get_cur_active(EMAC_BD_TYPE_e bdt)
|
||||
{
|
||||
uint32_t bd = 0;
|
||||
|
||||
bd = BL_RD_REG(EMAC_BASE, EMAC_TX_BD_NUM);
|
||||
|
||||
if (bdt == EMAC_BD_TYPE_TX) {
|
||||
bd &= EMAC_TXBDPTR_MSK;
|
||||
bd >>= EMAC_TXBDPTR_POS;
|
||||
}
|
||||
|
||||
if (bdt == EMAC_BD_TYPE_RX) {
|
||||
bd &= EMAC_RXBDPTR_MSK;
|
||||
bd >>= EMAC_RXBDPTR_POS;
|
||||
}
|
||||
|
||||
return bd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param index
|
||||
* @return int
|
||||
*/
|
||||
static int emac_bd_rx_enqueue(uint32_t index)
|
||||
{
|
||||
BL_Err_Type err = SUCCESS;
|
||||
|
||||
thiz->rxIndexEMAC = index;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param index
|
||||
* @return int
|
||||
*/
|
||||
static void emac_bd_rx_on_err(uint32_t index)
|
||||
{
|
||||
/* to do index - 1 */
|
||||
// uint32_t tmp_bd = 0;
|
||||
// tmp_bd = BL_RD_REG(EMAC_BASE, EMAC_TX_BD_NUM);
|
||||
// if (index == tmp_bd) {
|
||||
// index += (tmp_bd - 1);
|
||||
// } else {
|
||||
// index -= 1;
|
||||
// }
|
||||
// MSG("i:%x,csl%x\r\n", 5, thiz->bd[5].C_S_L);
|
||||
// MSG("i:%x,csl%x\r\n", 6, thiz->bd[6].C_S_L);
|
||||
// MSG("i:%x,csl%x\r\n", 7, thiz->bd[7].C_S_L);
|
||||
// MSG("i:%x,csl%x\r\n", 8, thiz->bd[8].C_S_L);
|
||||
// MSG("i:%x,csl%x\r\n", 9, thiz->bd[9].C_S_L);
|
||||
/* handle error */
|
||||
if (thiz->bd[index].C_S_L & EMAC_BD_FIELD_MSK(RX_OR)) {
|
||||
MSG("EMAC RX OR Error at %s:%d\r\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
if (thiz->bd[index].C_S_L & EMAC_BD_FIELD_MSK(RX_RE)) {
|
||||
MSG("MAC RX RE Error at %s:%d\r\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
if (thiz->bd[index].C_S_L & EMAC_BD_FIELD_MSK(RX_DN)) {
|
||||
MSG("MAC RX DN Error at %s:%d\r\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
if (thiz->bd[index].C_S_L & EMAC_BD_FIELD_MSK(RX_TL)) {
|
||||
MSG("MAC RX TL Error at %s:%d\r\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
if (thiz->bd[index].C_S_L & EMAC_BD_FIELD_MSK(RX_CRC)) {
|
||||
MSG("MAC RX CRC Error at %s:%d\r\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
if (thiz->bd[index].C_S_L & EMAC_BD_FIELD_MSK(RX_LC)) {
|
||||
MSG("MAC RX LC Error at %s:%d\r\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
thiz->bd[index].C_S_L &= ~0xff;
|
||||
/* RX BD is ready for RX */
|
||||
thiz->bd[index].C_S_L |= EMAC_BD_FIELD_MSK(RX_E);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this func will be called in ISR
|
||||
*
|
||||
* @param index
|
||||
* @return int
|
||||
*/
|
||||
static int emac_bd_tx_dequeue(uint32_t index)
|
||||
{
|
||||
BL_Err_Type err = SUCCESS;
|
||||
EMAC_BD_Desc_Type *DMADesc;
|
||||
|
||||
thiz->txIndexEMAC = index;
|
||||
DMADesc = &thiz->bd[thiz->txIndexEMAC];
|
||||
/* release this tx BD to SW (HW will do this) */
|
||||
DMADesc->C_S_L &= EMAC_BD_FIELD_UMSK(TX_RD);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param index
|
||||
* @return int
|
||||
*/
|
||||
static void emac_bd_tx_on_err(uint32_t index)
|
||||
{
|
||||
/* handle error */
|
||||
if (thiz->bd[index].C_S_L & EMAC_BD_FIELD_MSK(TX_UR)) {
|
||||
MSG("%s:%d\r\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
if (thiz->bd[index].C_S_L & EMAC_BD_FIELD_MSK(TX_RTRY)) {
|
||||
MSG("%s:%d\r\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
if (thiz->bd[index].C_S_L & EMAC_BD_FIELD_MSK(TX_RL)) {
|
||||
MSG("%s:%d\r\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
if (thiz->bd[index].C_S_L & EMAC_BD_FIELD_MSK(TX_LC)) {
|
||||
MSG("%s:%d\r\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
if (thiz->bd[index].C_S_L & EMAC_BD_FIELD_MSK(TX_DF)) {
|
||||
MSG("%s:%d\r\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
if (thiz->bd[index].C_S_L & EMAC_BD_FIELD_MSK(TX_CS)) {
|
||||
MSG("%s:%d\r\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
thiz->bd[index].C_S_L &= ~0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
__WEAK void emac_tx_done_callback_app(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
static void emac_tx_done_callback(void)
|
||||
{
|
||||
uint32_t index = 0;
|
||||
index = emac_bd_get_cur_active(EMAC_BD_TYPE_TX);
|
||||
|
||||
emac_bd_tx_dequeue(index);
|
||||
|
||||
emac_tx_done_callback_app();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
__WEAK void emac_tx_error_callback_app(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
static void emac_tx_error_callback(void)
|
||||
{
|
||||
uint32_t index = 0;
|
||||
|
||||
index = emac_bd_get_cur_active(EMAC_BD_TYPE_TX);
|
||||
|
||||
emac_bd_tx_on_err(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
__WEAK void emac_rx_done_callback_app(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
static void emac_rx_done_callback(void)
|
||||
{
|
||||
uint32_t index = 0;
|
||||
|
||||
index = emac_bd_get_cur_active(EMAC_BD_TYPE_RX);
|
||||
|
||||
emac_bd_rx_enqueue(index);
|
||||
|
||||
emac_rx_done_callback_app();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
__WEAK void emac_rx_error_callback_app(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
static void emac_rx_error_callback(void)
|
||||
{
|
||||
uint32_t index;
|
||||
|
||||
index = emac_bd_get_cur_active(EMAC_BD_TYPE_RX);
|
||||
|
||||
emac_bd_rx_on_err(index);
|
||||
|
||||
emac_rx_error_callback_app();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
__WEAK void emac_rx_busy_callback_app(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
static void emac_rx_busy_callback(void)
|
||||
{
|
||||
MSG("EMAC Rx busy at %s:%d\r\n", __func__, __LINE__);
|
||||
emac_rx_busy_callback_app();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param emac_cfg
|
||||
* @return int
|
||||
*/
|
||||
int emac_init(emac_device_t *emac_cfg)
|
||||
{
|
||||
EMAC_CFG_Type emacCfg = {
|
||||
.recvSmallFrame = ENABLE, /*!< Receive small frmae or not */
|
||||
.recvHugeFrame = DISABLE, /*!< Receive huge frmae(>64K bytes) or not */
|
||||
.padEnable = ENABLE, /*!< Enable padding for frame which is less than MINFL or not */
|
||||
.crcEnable = ENABLE, /*!< Enable hardware CRC or not */
|
||||
.noPreamble = DISABLE, /*!< Enable preamble or not */
|
||||
.recvBroadCast = ENABLE, /*!< Receive broadcast frame or not */
|
||||
.interFrameGapCheck = ENABLE, /*!< Check inter frame gap or not */
|
||||
.miiNoPreamble = ENABLE, /*!< Enable MII interface preamble or not */
|
||||
.miiClkDiv = 49, /*!< MII interface clock divider from bus clock */
|
||||
.maxTxRetry = 16, /*!< Maximum tx retry count */
|
||||
.interFrameGapValue = 24, /*!< Inter frame gap vaule in clock cycles(default 24)*/
|
||||
.minFrameLen = 64, /*!< Minimum frame length */
|
||||
.maxFrameLen = ETH_MAX_PACKET_SIZE, /*!< Maximum frame length */
|
||||
.collisionValid = 16, /*!< Collision valid value */
|
||||
.macAddr[0] = 0x18, /*!< MAC Address */
|
||||
.macAddr[1] = 0xB0,
|
||||
.macAddr[2] = 0x09,
|
||||
.macAddr[3] = 0x00,
|
||||
.macAddr[4] = 0x12,
|
||||
.macAddr[5] = 0x34,
|
||||
};
|
||||
BL_Err_Type err = SUCCESS;
|
||||
|
||||
/* init emac giio */
|
||||
emac_gpio_init();
|
||||
|
||||
memcpy(emacCfg.macAddr, emac_cfg->mac_addr, 6);
|
||||
#if EMAC_USE_INSIDE_CLOCK
|
||||
//enable audio clock */
|
||||
PDS_Enable_PLL_Clk(PDS_PLL_CLK_48M);
|
||||
PDS_Set_Audio_PLL_Freq(AUDIO_PLL_50000000_HZ);
|
||||
|
||||
GLB_Set_ETH_REF_O_CLK_Sel(GLB_ETH_REF_CLK_OUT_INSIDE_50M);
|
||||
#else
|
||||
GLB_Set_ETH_REF_O_CLK_Sel(GLB_ETH_REF_CLK_OUT_OUTSIDE_50M);
|
||||
#endif
|
||||
GLB_AHB_Slave1_Clock_Gate(DISABLE, BL_AHB_SLAVE1_EMAC);
|
||||
//GLB_Invert_ETH_RX_CLK(0);
|
||||
//GLB_Invert_ETH_TX_CLK(0);
|
||||
EMAC_Init(&emacCfg);
|
||||
|
||||
EMAC_Int_Callback_Install(EMAC_INT_TX_DONE_IDX, emac_tx_done_callback);
|
||||
EMAC_Int_Callback_Install(EMAC_INT_TX_ERROR_IDX, emac_tx_error_callback);
|
||||
|
||||
EMAC_Int_Callback_Install(EMAC_INT_RX_DONE_IDX, emac_rx_done_callback);
|
||||
EMAC_Int_Callback_Install(EMAC_INT_RX_ERROR_IDX, emac_rx_error_callback);
|
||||
|
||||
EMAC_Int_Callback_Install(EMAC_INT_RX_BUSY_IDX, emac_rx_busy_callback);
|
||||
|
||||
CPU_Interrupt_Enable(EMAC_IRQn);
|
||||
|
||||
EMAC_ClrIntStatus(EMAC_INT_ALL);
|
||||
EMAC_IntMask(EMAC_INT_ALL, UNMASK);
|
||||
|
||||
//EMAC_Enable();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param eth_tx_buff
|
||||
* @param tx_buf_count
|
||||
* @param eth_rx_buff
|
||||
* @param rx_buf_count
|
||||
* @return int
|
||||
*/
|
||||
int emac_bd_init(uint8_t *eth_tx_buff, uint8_t tx_buf_count, uint8_t *eth_rx_buff, uint8_t rx_buf_count)
|
||||
{
|
||||
BL_Err_Type err = SUCCESS;
|
||||
thiz = ðHandle;
|
||||
|
||||
/* init the BDs in emac with buffer address */
|
||||
err = EMAC_DMADescListInit(thiz, (uint8_t *)eth_tx_buff, tx_buf_count,
|
||||
(uint8_t *)eth_rx_buff, rx_buf_count);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param flags
|
||||
* @param len
|
||||
* @param data_in
|
||||
* @return int
|
||||
*/
|
||||
int emac_bd_tx_enqueue(uint32_t flags, uint32_t len, const uint8_t *data_in)
|
||||
{
|
||||
BL_Err_Type err = SUCCESS;
|
||||
EMAC_BD_Desc_Type *DMADesc;
|
||||
|
||||
DMADesc = &thiz->bd[thiz->txIndexCPU];
|
||||
|
||||
if (FULL_PACKET == flags) {
|
||||
// MSG("full packet,len:%d\r\n", len);
|
||||
flags = (EMAC_TX_COMMON_FLAGS | EMAC_BD_FIELD_MSK(TX_EOF));
|
||||
} else if (NOFULL_PACKET == flags) {
|
||||
// MSG("nofull packet\r\n");
|
||||
flags = EMAC_TX_COMMON_FLAGS;
|
||||
}
|
||||
|
||||
if (DMADesc->C_S_L & EMAC_BD_FIELD_MSK(TX_RD)) {
|
||||
/* no free BD, lost sync with DMA TX? */
|
||||
err = NORESC;
|
||||
// MSG_ERR(TAG"%s:%d\n", __func__, __LINE__);
|
||||
} else {
|
||||
DMADesc->Buffer = (uint32_t)data_in;
|
||||
// MSG("tx q flags:%d,len:%d,data:0x%x\r\n", flags, len, data_in);
|
||||
|
||||
// ARCH_MemCpy_Fast((void *)DMADesc->Buffer, data_in, len);
|
||||
|
||||
DMADesc->C_S_L = flags | (len << BD_TX_LEN_POS);
|
||||
|
||||
/* move to next TX BD */
|
||||
if ((++thiz->txIndexCPU) > thiz->txBuffLimit) {
|
||||
/* the last BD */
|
||||
DMADesc->C_S_L |= EMAC_BD_FIELD_MSK(TX_WR);
|
||||
/* wrap back */
|
||||
thiz->txIndexCPU = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param flags
|
||||
* @param len
|
||||
* @param data_out
|
||||
* @return int
|
||||
*/
|
||||
int emac_bd_rx_dequeue(uint32_t flags, uint32_t *len, uint8_t *data_out)
|
||||
{
|
||||
BL_Err_Type err = SUCCESS;
|
||||
EMAC_BD_Desc_Type *DMADesc;
|
||||
|
||||
DMADesc = &thiz->bd[thiz->rxIndexCPU];
|
||||
|
||||
if (DMADesc->C_S_L & EMAC_BD_FIELD_MSK(RX_E)) {
|
||||
/* current RX BD is empty */
|
||||
err = NORESC;
|
||||
*len = 0;
|
||||
} else {
|
||||
*len = (thiz->bd[thiz->rxIndexCPU].C_S_L & EMAC_BD_FIELD_MSK(RX_LEN)) >> BD_RX_LEN_POS;
|
||||
|
||||
if (data_out) {
|
||||
ARCH_MemCpy_Fast(data_out, (const void *)DMADesc->Buffer, *len);
|
||||
}
|
||||
|
||||
/* RX BD can be used for another receive */
|
||||
DMADesc->C_S_L |= EMAC_BD_FIELD_MSK(RX_E);
|
||||
|
||||
/* move to next RX BD */
|
||||
if ((++thiz->rxIndexCPU) > thiz->rxBuffLimit) {
|
||||
/* the last BD */
|
||||
DMADesc->C_S_L |= EMAC_BD_FIELD_MSK(RX_WR);
|
||||
/* wrap back */
|
||||
thiz->rxIndexCPU = thiz->txBuffLimit + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param phyAddress
|
||||
* @return int
|
||||
*/
|
||||
int emac_phy_set_address(uint16_t phyAddress)
|
||||
{
|
||||
EMAC_Phy_SetAddress(phyAddress);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param fullDuplex
|
||||
* @return int
|
||||
*/
|
||||
int emac_phy_config_full_duplex(uint8_t fullDuplex)
|
||||
{
|
||||
EMAC_Phy_Set_Full_Duplex(fullDuplex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param phyReg
|
||||
* @param regValue
|
||||
* @return int
|
||||
*/
|
||||
int emac_phy_reg_read(uint16_t phyReg, uint16_t *regValue)
|
||||
{
|
||||
if (EMAC_Phy_Read(phyReg, regValue) != SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param phyReg
|
||||
* @param regValue
|
||||
* @return int
|
||||
*/
|
||||
int emac_phy_reg_write(uint16_t phyReg, uint16_t regValue)
|
||||
{
|
||||
if (EMAC_Phy_Write(phyReg, regValue) != SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int emac_stop(void)
|
||||
{
|
||||
return EMAC_Disable();
|
||||
}
|
||||
|
||||
int emac_start(void)
|
||||
{
|
||||
EMAC_Enable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int emac_start_tx(void)
|
||||
{
|
||||
return EMAC_Enable_TX();
|
||||
}
|
||||
|
||||
int emac_stop_tx(void)
|
||||
{
|
||||
return EMAC_Disable_TX();
|
||||
}
|
||||
|
||||
int emac_start_rx(void)
|
||||
{
|
||||
return EMAC_Enable_RX();
|
||||
}
|
||||
|
||||
int emac_stop_rx(void)
|
||||
{
|
||||
return EMAC_Disable_RX();
|
||||
}
|
||||
@@ -1,379 +0,0 @@
|
||||
/**
|
||||
* @file hal_i2s.c
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
#include "hal_i2s.h"
|
||||
#include "hal_clock.h"
|
||||
#include "hal_dma.h"
|
||||
#include "bl702_i2s.h"
|
||||
#include "bl702_glb.h"
|
||||
#include "i2s_config.h"
|
||||
|
||||
static i2s_device_t i2sx_device[I2S_MAX_INDEX] = {
|
||||
#ifdef BSP_USING_I2S0
|
||||
I2S0_CONFIG,
|
||||
#endif
|
||||
};
|
||||
|
||||
int i2s_open(struct device *dev, uint16_t oflag)
|
||||
{
|
||||
i2s_device_t *i2s_device = (i2s_device_t *)dev;
|
||||
I2S_CFG_Type i2sCfg = { 0 };
|
||||
I2S_FifoCfg_Type fifoCfg = { 0 };
|
||||
|
||||
i2sCfg.audioFreqHz = system_clock_get(SYSTEM_CLOCK_AUPLL);
|
||||
|
||||
i2sCfg.sampleFreqHz = i2s_device->sampl_freq_hz;
|
||||
|
||||
/*!< default I2S msb first */
|
||||
i2sCfg.endianType = I2S_DATA_ENDIAN;
|
||||
|
||||
/* Config the I2S type */
|
||||
switch (i2s_device->interface_mode) {
|
||||
case I2S_MODE_STD:
|
||||
i2sCfg.modeType = I2S_MODE_I2S_LEFT;
|
||||
i2sCfg.fsMode = I2S_FS_MODE_EVEN;
|
||||
i2sCfg.dataOffset = 1;
|
||||
break;
|
||||
|
||||
case I2S_MODE_LEFT:
|
||||
i2sCfg.modeType = I2S_MODE_I2S_LEFT;
|
||||
i2sCfg.fsMode = I2S_FS_MODE_EVEN;
|
||||
i2sCfg.dataOffset = 0;
|
||||
break;
|
||||
|
||||
case I2S_MODE_RIGHT:
|
||||
i2sCfg.modeType = I2S_MODE_I2S_RIGHT;
|
||||
i2sCfg.fsMode = I2S_FS_MODE_EVEN;
|
||||
i2sCfg.dataOffset = 0;
|
||||
break;
|
||||
|
||||
case I2S_MODE_DSP_A:
|
||||
i2sCfg.modeType = I2S_MODE_I2S_DSP;
|
||||
i2sCfg.fsMode = I2S_FS_MODE_1T;
|
||||
i2sCfg.dataOffset = 1;
|
||||
break;
|
||||
|
||||
case I2S_MODE_DSP_B:
|
||||
i2sCfg.modeType = I2S_MODE_I2S_DSP;
|
||||
i2sCfg.fsMode = I2S_FS_MODE_1T;
|
||||
i2sCfg.dataOffset = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Config the frame/data Size */
|
||||
switch (i2s_device->frame_size) {
|
||||
case I2S_FRAME_LEN_8:
|
||||
i2sCfg.frameSize = I2S_SIZE_FRAME_8;
|
||||
break;
|
||||
|
||||
case I2S_FRAME_LEN_16:
|
||||
i2sCfg.frameSize = I2S_SIZE_FRAME_16;
|
||||
break;
|
||||
|
||||
case I2S_FRAME_LEN_24:
|
||||
i2sCfg.frameSize = I2S_SIZE_FRAME_24;
|
||||
break;
|
||||
|
||||
case I2S_FRAME_LEN_32:
|
||||
i2sCfg.frameSize = I2S_SIZE_FRAME_32;
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (i2s_device->data_size) {
|
||||
case I2S_DATA_LEN_8:
|
||||
i2sCfg.dataSize = I2S_SIZE_DATA_8;
|
||||
break;
|
||||
|
||||
case I2S_DATA_LEN_16:
|
||||
i2sCfg.dataSize = I2S_SIZE_DATA_16;
|
||||
break;
|
||||
|
||||
case I2S_DATA_LEN_24:
|
||||
i2sCfg.dataSize = I2S_SIZE_DATA_24;
|
||||
break;
|
||||
|
||||
case I2S_DATA_LEN_32:
|
||||
i2sCfg.dataSize = I2S_SIZE_DATA_32;
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
fifoCfg.lRMerge = DISABLE;
|
||||
fifoCfg.frameDataExchange = DISABLE;
|
||||
|
||||
/* Config the Channel number */
|
||||
switch (i2s_device->channel_num) {
|
||||
case I2S_FS_CHANNELS_NUM_MONO:
|
||||
i2sCfg.monoMode = ENABLE;
|
||||
i2sCfg.fsChannel = I2S_FS_CHANNELS_2;
|
||||
i2sCfg.monoModeChannel = I2S_MONO_CHANNEL;
|
||||
break;
|
||||
|
||||
case I2S_FS_CHANNELS_NUM_2:
|
||||
i2sCfg.monoMode = DISABLE;
|
||||
i2sCfg.fsChannel = I2S_FS_CHANNELS_2;
|
||||
|
||||
if (i2s_device->data_size == I2S_DATA_LEN_8 || i2s_device->data_size == I2S_DATA_LEN_16) {
|
||||
fifoCfg.lRMerge = ENABLE;
|
||||
fifoCfg.frameDataExchange = I2S_LR_EXCHANGE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case I2S_FS_CHANNELS_NUM_3:
|
||||
if ((i2s_device->interface_mode != I2S_MODE_DSP_A) && (i2s_device->interface_mode != I2S_MODE_DSP_B)) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
i2sCfg.monoMode = DISABLE;
|
||||
i2sCfg.fsChannel = I2S_FS_CHANNELS_3;
|
||||
break;
|
||||
|
||||
case I2S_FS_CHANNELS_NUM_4:
|
||||
if ((i2s_device->interface_mode != I2S_MODE_DSP_A) && (i2s_device->interface_mode != I2S_MODE_DSP_B)) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
i2sCfg.monoMode = DISABLE;
|
||||
i2sCfg.fsChannel = I2S_FS_CHANNELS_4;
|
||||
|
||||
default:
|
||||
return ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Config the bclk/fs invert */
|
||||
i2sCfg.bclkInvert = I2S_BCLK_INVERT;
|
||||
i2sCfg.fsInvert = I2S_FS_INVERT;
|
||||
|
||||
if (oflag & DEVICE_OFLAG_INT_TX) {
|
||||
}
|
||||
|
||||
if (oflag & DEVICE_OFLAG_INT_RX) {
|
||||
}
|
||||
|
||||
fifoCfg.txfifoDmaEnable = (oflag & DEVICE_OFLAG_DMA_TX) ? ENABLE : DISABLE;
|
||||
fifoCfg.rxfifoDmaEnable = (oflag & DEVICE_OFLAG_DMA_RX) ? ENABLE : DISABLE;
|
||||
fifoCfg.txFifoLevel = i2s_device->fifo_threshold;
|
||||
fifoCfg.rxFifoLevel = i2s_device->fifo_threshold;
|
||||
|
||||
/* I2S Init */
|
||||
I2S_Disable();
|
||||
I2S_Init(&i2sCfg);
|
||||
I2S_FifoConfig(&fifoCfg);
|
||||
|
||||
if (i2s_device->iis_mode == I2S_MODE_MASTER)
|
||||
I2S_Enable(I2S_ROLE_MASTER);
|
||||
else if (i2s_device->iis_mode == I2S_MODE_SLAVE)
|
||||
I2S_Enable(I2S_ROLE_SLAVE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2s_close(struct device *dev)
|
||||
{
|
||||
//i2s_device_t* uart_device = (i2s_device_t*)dev;
|
||||
I2S_Disable();
|
||||
GLB_AHB_Slave1_Reset(BL_AHB_SLAVE1_I2S);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2s_control(struct device *dev, int cmd, void *args)
|
||||
{
|
||||
i2s_device_t *i2s_device = (i2s_device_t *)dev;
|
||||
|
||||
I2S_CFG_Type i2sCfg;
|
||||
|
||||
switch (cmd) {
|
||||
case DEVICE_CTRL_SET_INT:
|
||||
for (uint16_t i = 0, j = 1; i < 8; i++, j <<= 1) {
|
||||
if ((uint32_t)args & j) {
|
||||
/* code */
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_CLR_INT:
|
||||
for (uint16_t i = 0, j = 1; i < 8; i++, j <<= 1) {
|
||||
if ((uint32_t)args & j) {
|
||||
/* code */
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_GET_INT:
|
||||
/* code */
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_RESUME:
|
||||
/* code */
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_SUSPEND:
|
||||
/* code */
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_CONFIG:
|
||||
/* code */
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_ATTACH_TX_DMA /* constant-expression */:
|
||||
i2s_device->tx_dma = (struct device *)args;
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_ATTACH_RX_DMA /* constant-expression */:
|
||||
i2s_device->rx_dma = (struct device *)args;
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_I2S_GET_TX_FIFO:
|
||||
return I2S_GetTxFIFO_AvlCnt();
|
||||
|
||||
case DEVICE_CTRL_I2S_GET_RX_FIFO:
|
||||
return I2S_GetRxFIFO_AvlCnt();
|
||||
|
||||
case DEVICE_CTRL_I2S_SET_SAMPL_FREQ:
|
||||
switch (i2s_device->frame_size) {
|
||||
case I2S_FRAME_LEN_8:
|
||||
i2sCfg.frameSize = I2S_SIZE_FRAME_8;
|
||||
break;
|
||||
|
||||
case I2S_FRAME_LEN_16:
|
||||
i2sCfg.frameSize = I2S_SIZE_FRAME_16;
|
||||
break;
|
||||
|
||||
case I2S_FRAME_LEN_24:
|
||||
i2sCfg.frameSize = I2S_SIZE_FRAME_24;
|
||||
break;
|
||||
|
||||
case I2S_FRAME_LEN_32:
|
||||
i2sCfg.frameSize = I2S_SIZE_FRAME_32;
|
||||
break;
|
||||
default:
|
||||
return ERROR;
|
||||
break;
|
||||
}
|
||||
i2sCfg.audioFreqHz = system_clock_get(SYSTEM_CLOCK_AUPLL);
|
||||
i2sCfg.sampleFreqHz = (uint32_t)args;
|
||||
I2S_SetBclkPeriod(&i2sCfg);
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int i2s_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size)
|
||||
{
|
||||
i2s_device_t *i2s_device = (i2s_device_t *)dev;
|
||||
|
||||
if (dev->oflag & DEVICE_OFLAG_DMA_TX) {
|
||||
struct device *dma_ch = (struct device *)i2s_device->tx_dma;
|
||||
|
||||
if (!dma_ch) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i2s_device->id == 0) {
|
||||
dma_reload(dma_ch, (uint32_t)buffer, (uint32_t)DMA_ADDR_I2S_TDR, size);
|
||||
dma_channel_start(dma_ch);
|
||||
} else if (i2s_device->id == 1) {
|
||||
dma_reload(dma_ch, (uint32_t)buffer, (uint32_t)DMA_ADDR_I2S_TDR, size);
|
||||
dma_channel_start(dma_ch);
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int i2s_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size)
|
||||
{
|
||||
i2s_device_t *i2s_device = (i2s_device_t *)dev;
|
||||
|
||||
if (dev->oflag & DEVICE_OFLAG_DMA_RX) {
|
||||
struct device *dma_ch = (struct device *)i2s_device->rx_dma;
|
||||
|
||||
if (!dma_ch) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i2s_device->id == 0) {
|
||||
dma_reload(dma_ch, (uint32_t)DMA_ADDR_I2S_RDR, (uint32_t)buffer, size);
|
||||
dma_channel_start(dma_ch);
|
||||
} else if (i2s_device->id == 1) {
|
||||
dma_reload(dma_ch, (uint32_t)DMA_ADDR_I2S_RDR, (uint32_t)buffer, size);
|
||||
dma_channel_start(dma_ch);
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int i2s_register(enum i2s_index_type index, const char *name)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
if (I2S_MAX_INDEX == 0) {
|
||||
return -DEVICE_EINVAL;
|
||||
}
|
||||
|
||||
dev = &(i2sx_device[index].parent);
|
||||
|
||||
dev->open = i2s_open;
|
||||
dev->close = i2s_close;
|
||||
dev->control = i2s_control;
|
||||
dev->write = i2s_write;
|
||||
dev->read = i2s_read;
|
||||
|
||||
dev->type = DEVICE_CLASS_I2S;
|
||||
dev->handle = NULL;
|
||||
|
||||
return device_register(dev, name);
|
||||
}
|
||||
|
||||
void i2s_isr(i2s_device_t *handle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void I2S_IRQ(void)
|
||||
{
|
||||
i2s_isr(&i2sx_device[0]);
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
/**
|
||||
* @file hal_keyscan.c
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
#include "hal_keyscan.h"
|
||||
#include "kys_reg.h"
|
||||
#include "bl702_glb.h"
|
||||
|
||||
#ifdef BSP_USING_KEYSCAN
|
||||
static void KeyScan_IRQ(void);
|
||||
#endif
|
||||
|
||||
static keyscan_device_t keyscan_device[KEYSCAN_MAX_INDEX] = {
|
||||
#ifdef BSP_USING_KEYSCAN
|
||||
KEYSCAN_CONFIG
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @param oflag
|
||||
* @return int
|
||||
*/
|
||||
int keyscan_open(struct device *dev, uint16_t oflag)
|
||||
{
|
||||
uint32_t tmpVal;
|
||||
keyscan_device_t *keyscan_device_local = (keyscan_device_t *)dev;
|
||||
|
||||
tmpVal = BL_RD_REG(KYS_BASE, KYS_KS_CTRL);
|
||||
/* Set col and row */
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, KYS_COL_NUM, keyscan_device_local->col_num - 1);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, KYS_ROW_NUM, keyscan_device_local->row_num - 1);
|
||||
|
||||
/* Set idle duration between column scans */
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, KYS_RC_EXT, 0);
|
||||
|
||||
/* ghost key event detection not support*/
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, KYS_GHOST_EN, 0);
|
||||
|
||||
if (keyscan_device_local->deglitch_count) {
|
||||
/* Enable or disable deglitch function */
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, KYS_DEG_EN, 1);
|
||||
|
||||
/* Set deglitch count */
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, KYS_DEG_CNT, keyscan_device_local->deglitch_count);
|
||||
} else {
|
||||
/* Enable or disable deglitch function */
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, KYS_DEG_EN, 0);
|
||||
|
||||
/* Set deglitch count */
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, KYS_DEG_CNT, 0);
|
||||
}
|
||||
|
||||
/* Write back */
|
||||
BL_WR_REG(KYS_BASE, KYS_KS_CTRL, tmpVal);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int keyscan_control(struct device *dev, int cmd, void *args)
|
||||
{
|
||||
switch (cmd) {
|
||||
case DEVICE_CTRL_SET_INT /* constant-expression */:
|
||||
#ifdef BSP_USING_KEYSCAN
|
||||
Interrupt_Handler_Register(KYS_IRQn, KeyScan_IRQ);
|
||||
#endif
|
||||
BL_WR_REG(KYS_BASE, KYS_KS_INT_EN, 1);
|
||||
CPU_Interrupt_Enable(KYS_IRQn);
|
||||
break;
|
||||
case DEVICE_CTRL_CLR_INT /* constant-expression */:
|
||||
Interrupt_Handler_Register(KYS_IRQn, NULL);
|
||||
BL_WR_REG(KYS_BASE, KYS_KS_INT_EN, 0);
|
||||
CPU_Interrupt_Disable(KYS_IRQn);
|
||||
break;
|
||||
case DEVICE_CTRL_GET_INT:
|
||||
return (BL_RD_REG(KYS_BASE, KYS_KS_INT_STS) & 0xf);
|
||||
case DEVICE_CTRL_RESUME: {
|
||||
uint32_t tmpVal;
|
||||
|
||||
tmpVal = BL_RD_REG(KYS_BASE, KYS_KS_CTRL);
|
||||
BL_WR_REG(KYS_BASE, KYS_KS_CTRL, BL_SET_REG_BIT(tmpVal, KYS_KS_EN));
|
||||
} break;
|
||||
case DEVICE_CTRL_SUSPEND: {
|
||||
uint32_t tmpVal;
|
||||
|
||||
tmpVal = BL_RD_REG(KYS_BASE, KYS_KS_CTRL);
|
||||
BL_WR_REG(KYS_BASE, KYS_KS_CTRL, BL_CLR_REG_BIT(tmpVal, KYS_KS_EN));
|
||||
} break;
|
||||
case DEVICE_CTRL_KEYSCAN_GET_KEYCODE: {
|
||||
uint32_t *key_code = (uint32_t *)args;
|
||||
*key_code = BL_RD_REG(KYS_BASE, KYS_KEYCODE_VALUE);
|
||||
BL_WR_REG(KYS_BASE, KYS_KEYCODE_CLR, 0xf);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param index
|
||||
* @param name
|
||||
* @param flag
|
||||
* @return int
|
||||
*/
|
||||
int keyscan_register(enum keyscan_index_type index, const char *name)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
if (KEYSCAN_MAX_INDEX == 0) {
|
||||
return -DEVICE_EINVAL;
|
||||
}
|
||||
|
||||
dev = &(keyscan_device[index].parent);
|
||||
|
||||
dev->open = keyscan_open;
|
||||
dev->close = NULL;
|
||||
dev->control = keyscan_control;
|
||||
dev->write = NULL;
|
||||
dev->read = NULL;
|
||||
|
||||
dev->type = DEVICE_CLASS_KEYSCAN;
|
||||
dev->handle = NULL;
|
||||
|
||||
return device_register(dev, name);
|
||||
}
|
||||
|
||||
#if defined(BSP_USING_KEYSCAN)
|
||||
static void KeyScan_IRQ(void)
|
||||
{
|
||||
if (keyscan_device[KEYSCAN_INDEX].parent.callback) {
|
||||
keyscan_device[KEYSCAN_INDEX].parent.callback(&keyscan_device[KEYSCAN_INDEX].parent, (void *)(BL_RD_REG(KYS_BASE, KYS_KEYCODE_VALUE)), 0, KEYSCAN_EVENT_TRIG);
|
||||
}
|
||||
|
||||
BL_WR_REG(KYS_BASE, KYS_KEYCODE_CLR, 0xf);
|
||||
}
|
||||
#endif
|
||||
@@ -1,131 +0,0 @@
|
||||
/**
|
||||
* @file hal_mjpeg.c
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
#include "bl702_mjpeg.h"
|
||||
#include "bl702_glb.h"
|
||||
#include "hal_mjpeg.h"
|
||||
|
||||
void mjpeg_init(mjpeg_device_t *mjpeg_cfg)
|
||||
{
|
||||
MJPEG_Packet_Type packetCfg = { 0 };
|
||||
|
||||
MJPEG_CFG_Type mjpegCfg = {
|
||||
.burst = MJPEG_BURST_INCR16,
|
||||
.quality = mjpeg_cfg->quality,
|
||||
.yuv = mjpeg_cfg->yuv_format,
|
||||
.waitCount = 0x400,
|
||||
.bufferMjpeg = mjpeg_cfg->write_buffer_addr,
|
||||
.sizeMjpeg = mjpeg_cfg->write_buffer_size,
|
||||
.bufferCamYY = mjpeg_cfg->read_buffer_addr,
|
||||
.sizeCamYY = mjpeg_cfg->read_buffer_size,
|
||||
.bufferCamUV = 0,
|
||||
.sizeCamUV = 0,
|
||||
.resolutionX = mjpeg_cfg->resolution_x,
|
||||
.resolutionY = mjpeg_cfg->resolution_y,
|
||||
.bitOrderEnable = ENABLE,
|
||||
.evenOrderEnable = ENABLE,
|
||||
.swapModeEnable = DISABLE,
|
||||
.overStopEnable = ENABLE,
|
||||
.reflectDmy = DISABLE,
|
||||
.verticalDmy = DISABLE,
|
||||
.horizationalDmy = DISABLE,
|
||||
};
|
||||
|
||||
GLB_AHB_Slave1_Clock_Gate(DISABLE, BL_AHB_SLAVE1_MJPEG);
|
||||
|
||||
uint32_t tmpVal;
|
||||
|
||||
/* Disable mjpeg module */
|
||||
tmpVal = BL_RD_REG(MJPEG_BASE, MJPEG_CONTROL_1);
|
||||
tmpVal = BL_CLR_REG_BIT(tmpVal, MJPEG_REG_MJPEG_ENABLE);
|
||||
BL_WR_REG(MJPEG_BASE, MJPEG_CONTROL_1, tmpVal);
|
||||
|
||||
MJPEG_Init(&mjpegCfg);
|
||||
|
||||
if (mjpeg_cfg->packet_cut_mode & MJPEG_PACKET_ADD_DEFAULT) {
|
||||
packetCfg.packetEnable = ENABLE;
|
||||
packetCfg.packetHead = mjpeg_cfg->packet_head_length;
|
||||
packetCfg.packetBody = mjpeg_cfg->packet_body_length;
|
||||
packetCfg.packetTail = mjpeg_cfg->packet_tail_length;
|
||||
}
|
||||
|
||||
if (mjpeg_cfg->packet_cut_mode & MJPEG_PACKET_ADD_FRAME_HEAD) {
|
||||
packetCfg.frameHead = mjpeg_cfg->frame_head_length;
|
||||
}
|
||||
|
||||
if (mjpeg_cfg->packet_cut_mode & MJPEG_PACKET_ADD_FRAME_TAIL) {
|
||||
packetCfg.frameTail = ENABLE;
|
||||
}
|
||||
|
||||
if (mjpeg_cfg->packet_cut_mode & MJPEG_PACKET_ADD_END_TAIL) {
|
||||
packetCfg.endToTail = ENABLE;
|
||||
}
|
||||
|
||||
MJPEG_Packet_Config(&packetCfg);
|
||||
|
||||
if (mjpeg_cfg->yuv_format == MJPEG_YUV_FORMAT_YUV422_INTERLEAVE) {
|
||||
MJPEG_Set_YUYV_Order_Interleave(1, 0, 3, 2);
|
||||
}
|
||||
}
|
||||
|
||||
void mjpeg_start(void)
|
||||
{
|
||||
uint32_t tmpVal;
|
||||
|
||||
/* Enable mjpeg module */
|
||||
tmpVal = BL_RD_REG(MJPEG_BASE, MJPEG_CONTROL_1);
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, MJPEG_REG_MJPEG_ENABLE);
|
||||
BL_WR_REG(MJPEG_BASE, MJPEG_CONTROL_1, tmpVal);
|
||||
}
|
||||
|
||||
void mjpeg_stop(void)
|
||||
{
|
||||
uint32_t tmpVal;
|
||||
|
||||
/* Disable mjpeg module */
|
||||
tmpVal = BL_RD_REG(MJPEG_BASE, MJPEG_CONTROL_1);
|
||||
tmpVal = BL_CLR_REG_BIT(tmpVal, MJPEG_REG_MJPEG_ENABLE);
|
||||
BL_WR_REG(MJPEG_BASE, MJPEG_CONTROL_1, tmpVal);
|
||||
}
|
||||
|
||||
uint8_t mjpeg_get_one_frame(uint8_t **pic, uint32_t *len, uint8_t *q)
|
||||
{
|
||||
MJPEG_Frame_Info info;
|
||||
arch_memset(&info, 0, sizeof(info));
|
||||
|
||||
MJPEG_Get_Frame_Info(&info);
|
||||
|
||||
if (info.validFrames == 0) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
*pic = (uint8_t *)(info.curFrameAddr);
|
||||
*len = info.curFrameBytes;
|
||||
*q = info.curFrameQ;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void mjpeg_drop_one_frame(void)
|
||||
{
|
||||
MJPEG_Pop_Frame();
|
||||
}
|
||||
@@ -1,290 +0,0 @@
|
||||
/**
|
||||
* @file hal_qdec.c
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "hal_qdec.h"
|
||||
#include "qdec_reg.h"
|
||||
#include "bl702_qdec.h"
|
||||
#include "bl702_gpio.h"
|
||||
#include "bl702_glb.h"
|
||||
|
||||
static qdec_device_t qdecx_device[QDEC_MAX_INDEX] = {
|
||||
#ifdef BSP_USING_QDEC0
|
||||
QDEC0_CONFIG,
|
||||
#endif
|
||||
#ifdef BSP_USING_QDEC1
|
||||
QDEC1_CONFIG,
|
||||
#endif
|
||||
#ifdef BSP_USING_QDEC2
|
||||
QDEC2_CONFIG,
|
||||
#endif
|
||||
};
|
||||
#ifdef BSP_USING_QDEC0
|
||||
static void QDEC0_IRQ(void);
|
||||
#endif
|
||||
#ifdef BSP_USING_QDEC1
|
||||
static void QDEC1_IRQ(void);
|
||||
#endif
|
||||
#ifdef BSP_USING_QDEC2
|
||||
static void QDEC2_IRQ(void);
|
||||
#endif
|
||||
|
||||
int qdec_open(struct device *dev, uint16_t oflag)
|
||||
{
|
||||
qdec_device_t *qdec_device = (qdec_device_t *)dev;
|
||||
QDEC_CFG_Type qdec_cfg = { 0 };
|
||||
|
||||
QDEC_DeInit(qdec_device->id);
|
||||
|
||||
qdec_cfg.sampleCfg.sampleMod = qdec_device->sample_mode;
|
||||
qdec_cfg.sampleCfg.samplePeriod = qdec_device->sample_period;
|
||||
qdec_cfg.reportCfg.reportMod = qdec_device->report_mode;
|
||||
qdec_cfg.reportCfg.reportPeriod = qdec_device->report_period;
|
||||
qdec_cfg.ledCfg.ledEn = qdec_device->led_en;
|
||||
qdec_cfg.ledCfg.ledSwap = qdec_device->led_swap;
|
||||
qdec_cfg.ledCfg.ledPeriod = qdec_device->led_period;
|
||||
qdec_cfg.deglitchCfg.deglitchEn = qdec_device->deglitch_en;
|
||||
qdec_cfg.deglitchCfg.deglitchStrength = qdec_device->deglitch_strength;
|
||||
qdec_cfg.accMod = qdec_device->acc_mode;
|
||||
|
||||
QDEC_Init(qdec_device->id, &qdec_cfg);
|
||||
|
||||
if (oflag & DEVICE_OFLAG_INT_RX) {
|
||||
#ifdef BSP_USING_QDEC0
|
||||
if (qdec_device->id == QDEC0_ID) {
|
||||
Interrupt_Handler_Register(QDEC0_IRQn, QDEC0_IRQ);
|
||||
}
|
||||
#endif
|
||||
#ifdef BSP_USING_QDEC1
|
||||
if (qdec_device->id == QDEC1_ID) {
|
||||
Interrupt_Handler_Register(QDEC1_IRQn, QDEC1_IRQ);
|
||||
QDEC_SetIntMask(qdec_device->id, QDEC_INT_REPORT, MASK);
|
||||
QDEC_SetIntMask(qdec_device->id, QDEC_INT_SAMPLE, MASK);
|
||||
QDEC_SetIntMask(qdec_device->id, QDEC_INT_ERROR, MASK);
|
||||
QDEC_SetIntMask(qdec_device->id, QDEC_INT_OVERFLOW, MASK);
|
||||
// CPU_Interrupt_Enable(QDEC1_IRQn);
|
||||
}
|
||||
#endif
|
||||
#ifdef BSP_USING_QDEC2
|
||||
if (qdec_device->id == QDEC2_ID) {
|
||||
Interrupt_Handler_Register(QDEC2_IRQn, QDEC2_IRQ);
|
||||
QDEC_SetIntMask(qdec_device->id, QDEC_INT_REPORT, MASK);
|
||||
QDEC_SetIntMask(qdec_device->id, QDEC_INT_SAMPLE, MASK);
|
||||
QDEC_SetIntMask(qdec_device->id, QDEC_INT_ERROR, MASK);
|
||||
QDEC_SetIntMask(qdec_device->id, QDEC_INT_OVERFLOW, MASK);
|
||||
// CPU_Interrupt_Enable(QDEC2_IRQn);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qdec_close(struct device *dev)
|
||||
{
|
||||
qdec_device_t *qdec_device = (qdec_device_t *)dev;
|
||||
|
||||
QDEC_Disable(qdec_device->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qdec_control(struct device *dev, int cmd, void *args)
|
||||
{
|
||||
qdec_device_t *qdec_device = (qdec_device_t *)dev;
|
||||
|
||||
switch (cmd) {
|
||||
case DEVICE_CTRL_SET_INT: {
|
||||
uint32_t offset = __builtin_ctz((uint32_t)args);
|
||||
while (offset < 5) {
|
||||
if ((uint32_t)args & (1 << offset)) {
|
||||
QDEC_SetIntMask(qdec_device->id, offset, UNMASK);
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
if (qdec_device->id == QDEC0_ID) {
|
||||
CPU_Interrupt_Enable(QDEC0_IRQn);
|
||||
} else if (qdec_device->id == QDEC1_ID) {
|
||||
CPU_Interrupt_Enable(QDEC1_IRQn);
|
||||
} else if (qdec_device->id == QDEC2_ID) {
|
||||
CPU_Interrupt_Enable(QDEC2_IRQn);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_CTRL_CLR_INT: {
|
||||
uint32_t offset = __builtin_ctz((uint32_t)args);
|
||||
while (offset < 5) {
|
||||
if ((uint32_t)args & (1 << offset)) {
|
||||
QDEC_SetIntMask(qdec_device->id, offset, MASK);
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
if (qdec_device->id == QDEC0_ID) {
|
||||
CPU_Interrupt_Disable(QDEC0_IRQn);
|
||||
} else if (qdec_device->id == QDEC1_ID) {
|
||||
CPU_Interrupt_Disable(QDEC1_IRQn);
|
||||
} else if (qdec_device->id == QDEC2_ID) {
|
||||
CPU_Interrupt_Disable(QDEC2_IRQn);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_CTRL_GET_INT /* constant-expression */:
|
||||
/* code */
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_CONFIG /* constant-expression */:
|
||||
/* code */
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_RESUME /* constant-expression */: {
|
||||
/* Enable timer */
|
||||
QDEC_Enable(qdec_device->id);
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_CTRL_SUSPEND /* constant-expression */: {
|
||||
QDEC_Disable(qdec_device->id);
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_CTRL_GET_SAMPLE_VAL: {
|
||||
return QDEC_Get_Sample_Val(qdec_device->id);
|
||||
}
|
||||
|
||||
case DEVICE_CTRL_GET_SAMPLE_DIR: {
|
||||
return QDEC_Get_Sample_Direction(qdec_device->id);
|
||||
}
|
||||
|
||||
case DEVICE_CTRL_GET_ERROR_CNT: {
|
||||
return QDEC_Get_Err_Cnt(qdec_device->id);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qdec_register(enum qdec_index_type index, const char *name)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
if (QDEC_MAX_INDEX == 0) {
|
||||
return -DEVICE_EINVAL;
|
||||
}
|
||||
|
||||
dev = &(qdecx_device[index].parent);
|
||||
|
||||
dev->open = qdec_open;
|
||||
dev->close = qdec_close;
|
||||
dev->control = qdec_control;
|
||||
dev->write = NULL;
|
||||
dev->read = NULL; //qdec_read;
|
||||
|
||||
dev->type = DEVICE_CLASS_QDEC;
|
||||
dev->handle = NULL;
|
||||
|
||||
return device_register(dev, name);
|
||||
}
|
||||
|
||||
void qdec_isr(qdec_device_t *handle)
|
||||
{
|
||||
uint32_t tmp_sts = 0;
|
||||
uint32_t tmp_val = 0;
|
||||
uint32_t tmp_clr = 0;
|
||||
uint32_t tmp_clr_val = 0;
|
||||
|
||||
if (handle->id == QDEC0_ID) {
|
||||
tmp_sts = BL_RD_WORD(QDEC0_BASE + QDEC0_INT_STS_OFFSET);
|
||||
tmp_clr = QDEC0_BASE + QDEC0_INT_CLR_OFFSET;
|
||||
tmp_clr_val = BL_RD_WORD(tmp_clr);
|
||||
tmp_val = BL_RD_REG(QDEC0_BASE, QDEC0_INT_EN);
|
||||
} else if (handle->id == QDEC1_ID) {
|
||||
tmp_sts = BL_RD_WORD(QDEC0_BASE + QDEC1_INT_STS_OFFSET);
|
||||
tmp_clr = QDEC0_BASE + QDEC1_INT_CLR_OFFSET;
|
||||
tmp_clr_val = BL_RD_WORD(tmp_clr);
|
||||
tmp_val = BL_RD_REG(QDEC1_BASE, QDEC0_INT_EN);
|
||||
} else if (handle->id == QDEC2_ID) {
|
||||
tmp_sts = BL_RD_WORD(QDEC0_BASE + QDEC2_INT_STS_OFFSET);
|
||||
tmp_clr = QDEC0_BASE + QDEC2_INT_CLR_OFFSET;
|
||||
tmp_clr_val = BL_RD_WORD(tmp_clr);
|
||||
tmp_val = BL_RD_REG(QDEC2_BASE, QDEC0_INT_EN);
|
||||
}
|
||||
|
||||
if (!handle->parent.callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* qdec report intterupt */
|
||||
if (!(BL_GET_REG_BITS_VAL(tmp_val, QDEC_RPT_RDY_EN) ? UNMASK : MASK)) {
|
||||
if (BL_IS_REG_BIT_SET(tmp_sts, QDEC_RPT_RDY_STS)) {
|
||||
BL_WR_WORD(tmp_clr, BL_SET_REG_BIT(tmp_clr_val, QDEC_RPT_RDY_CLR));
|
||||
handle->parent.callback(&handle->parent, NULL, 0, QDEC_REPORT_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
/* qdec sample intterupt */
|
||||
if (!(BL_GET_REG_BITS_VAL(tmp_val, QDEC_SPL_RDY_EN) ? UNMASK : MASK)) {
|
||||
if (BL_IS_REG_BIT_SET(tmp_sts, QDEC_SPL_RDY_STS)) {
|
||||
BL_WR_WORD(tmp_clr, BL_SET_REG_BIT(tmp_clr_val, QDEC_SPL_RDY_CLR));
|
||||
handle->parent.callback(&handle->parent, NULL, 0, QDEC_SAMPLE_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
/* qdec error intterupt */
|
||||
if (!(BL_GET_REG_BITS_VAL(tmp_val, QDEC_DBL_RDY_EN) ? UNMASK : MASK)) {
|
||||
if (BL_IS_REG_BIT_SET(tmp_sts, QDEC_DBL_RDY_STS)) {
|
||||
BL_WR_WORD(tmp_clr, BL_SET_REG_BIT(tmp_clr_val, QDEC_DBL_RDY_CLR));
|
||||
handle->parent.callback(&handle->parent, NULL, 0, QDEC_ERROR_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
/* qdec overflow intterupt */
|
||||
if (!(BL_GET_REG_BITS_VAL(tmp_val, QDEC_OVERFLOW_EN) ? UNMASK : MASK)) {
|
||||
if (BL_IS_REG_BIT_SET(tmp_sts, QDEC_OVERFLOW_STS)) {
|
||||
BL_WR_WORD(tmp_clr, BL_SET_REG_BIT(tmp_clr_val, QDEC_OVERFLOW_CLR));
|
||||
handle->parent.callback(&handle->parent, NULL, 0, QDEC_OVERFLOW_EVENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BSP_USING_QDEC0
|
||||
static void QDEC0_IRQ(void)
|
||||
{
|
||||
qdec_isr(&qdecx_device[QDEC0_INDEX]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_QDEC1
|
||||
static void QDEC1_IRQ(void)
|
||||
{
|
||||
qdec_isr(&qdecx_device[QDEC1_INDEX]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_QDEC2
|
||||
static void QDEC2_IRQ(void)
|
||||
{
|
||||
qdec_isr(&qdecx_device[QDEC2_INDEX]);
|
||||
}
|
||||
#endif
|
||||
@@ -1,537 +0,0 @@
|
||||
/**
|
||||
* @file hal_spi.c
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
#include "hal_spi.h"
|
||||
#include "hal_dma.h"
|
||||
#include "bl702_glb.h"
|
||||
#include "bl702_spi.h"
|
||||
|
||||
#ifdef BSP_USING_SPI0
|
||||
static void SPI0_IRQ(void);
|
||||
#endif
|
||||
|
||||
static spi_device_t spix_device[SPI_MAX_INDEX] = {
|
||||
#ifdef BSP_USING_SPI0
|
||||
SPI0_CONFIG,
|
||||
#endif
|
||||
};
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @param oflag
|
||||
* @return int
|
||||
*/
|
||||
int spi_open(struct device *dev, uint16_t oflag)
|
||||
{
|
||||
spi_device_t *spi_device = (spi_device_t *)dev;
|
||||
SPI_CFG_Type spiCfg = { 0 };
|
||||
SPI_FifoCfg_Type fifoCfg = { 0 };
|
||||
|
||||
if (spi_device->pin_swap_enable) {
|
||||
GLB_Swap_SPI_0_MOSI_With_MISO(ENABLE);
|
||||
}
|
||||
|
||||
/* Enable uart interrupt*/
|
||||
CPU_Interrupt_Disable(SPI_IRQn);
|
||||
SPI_IntMask(spi_device->id, SPI_INT_ALL, MASK);
|
||||
|
||||
SPI_Disable(spi_device->id, spi_device->mode);
|
||||
|
||||
GLB_Set_SPI_0_ACT_MOD_Sel(spi_device->mode);
|
||||
|
||||
/* Set SPI clock */
|
||||
SPI_ClockCfg_Type clockCfg = {
|
||||
2, /* Length of start condition */
|
||||
2, /* Length of stop condition */
|
||||
2, /* Length of data phase 0,affecting clock */
|
||||
2, /* Length of data phase 1,affecting clock */
|
||||
2 /* Length of interval between frame */
|
||||
};
|
||||
|
||||
if (spi_device->clk > 72 * 1000000) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t length = 72 * 1000000 / spi_device->clk;
|
||||
|
||||
if (!(length % 2)) {
|
||||
clockCfg.dataPhase0Len = length / 2;
|
||||
clockCfg.dataPhase1Len = length / 2;
|
||||
} else {
|
||||
clockCfg.dataPhase0Len = length / 2;
|
||||
clockCfg.dataPhase1Len = length / 2 + 1;
|
||||
}
|
||||
|
||||
SPI_ClockConfig(spi_device->id, &clockCfg);
|
||||
|
||||
spiCfg.continuousEnable = 1;
|
||||
|
||||
if (spi_device->direction == SPI_LSB_BYTE0_DIRECTION_FIRST) {
|
||||
spiCfg.bitSequence = SPI_BIT_INVERSE_LSB_FIRST;
|
||||
spiCfg.byteSequence = SPI_BYTE_INVERSE_BYTE0_FIRST;
|
||||
} else if (spi_device->direction == SPI_LSB_BYTE3_DIRECTION_FIRST) {
|
||||
spiCfg.bitSequence = SPI_BIT_INVERSE_LSB_FIRST;
|
||||
spiCfg.byteSequence = SPI_BYTE_INVERSE_BYTE3_FIRST;
|
||||
} else if (spi_device->direction == SPI_MSB_BYTE0_DIRECTION_FIRST) {
|
||||
spiCfg.bitSequence = SPI_BIT_INVERSE_MSB_FIRST;
|
||||
spiCfg.byteSequence = SPI_BYTE_INVERSE_BYTE0_FIRST;
|
||||
} else if (spi_device->direction == SPI_MSB_BYTE3_DIRECTION_FIRST) {
|
||||
spiCfg.bitSequence = SPI_BIT_INVERSE_MSB_FIRST;
|
||||
spiCfg.byteSequence = SPI_BYTE_INVERSE_BYTE3_FIRST;
|
||||
}
|
||||
|
||||
spiCfg.clkPolarity = spi_device->clk_polaraity;
|
||||
spiCfg.clkPhaseInv = spi_device->clk_phase;
|
||||
spiCfg.frameSize = spi_device->datasize;
|
||||
|
||||
if (spi_device->delitch_cnt) {
|
||||
spiCfg.deglitchEnable = 1;
|
||||
}
|
||||
|
||||
/* SPI config */
|
||||
SPI_Init(spi_device->id, &spiCfg);
|
||||
|
||||
SPI_SetDeglitchCount(spi_device->id, spi_device->delitch_cnt);
|
||||
|
||||
fifoCfg.txFifoThreshold = spi_device->fifo_threshold;
|
||||
fifoCfg.txFifoDmaEnable = DISABLE;
|
||||
fifoCfg.rxFifoThreshold = spi_device->fifo_threshold;
|
||||
fifoCfg.rxFifoDmaEnable = DISABLE;
|
||||
|
||||
if (oflag & DEVICE_OFLAG_INT_TX || oflag & DEVICE_OFLAG_INT_RX) {
|
||||
#ifdef BSP_USING_SPI0
|
||||
Interrupt_Handler_Register(SPI_IRQn, SPI0_IRQ);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (oflag & DEVICE_OFLAG_DMA_TX) {
|
||||
fifoCfg.txFifoDmaEnable = ENABLE;
|
||||
}
|
||||
|
||||
if (oflag & DEVICE_OFLAG_DMA_RX) {
|
||||
fifoCfg.rxFifoDmaEnable = ENABLE;
|
||||
}
|
||||
|
||||
SPI_FifoConfig(spi_device->id, &fifoCfg);
|
||||
/* Enable spi master mode */
|
||||
SPI_Enable(spi_device->id, spi_device->mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @return int
|
||||
*/
|
||||
int spi_close(struct device *dev)
|
||||
{
|
||||
spi_device_t *spi_device = (spi_device_t *)dev;
|
||||
|
||||
SPI_Disable(spi_device->id, spi_device->mode);
|
||||
GLB_AHB_Slave1_Reset(BL_AHB_SLAVE1_SPI);
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @param cmd
|
||||
* @param args
|
||||
* @return int
|
||||
*/
|
||||
int spi_control(struct device *dev, int cmd, void *args)
|
||||
{
|
||||
spi_device_t *spi_device = (spi_device_t *)dev;
|
||||
|
||||
switch (cmd) {
|
||||
case DEVICE_CTRL_SET_INT /* constant-expression */:
|
||||
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_CLR_INT /* constant-expression */:
|
||||
/* code */
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_GET_INT /* constant-expression */:
|
||||
/* code */
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_RESUME:
|
||||
/* code */
|
||||
SPI_Enable(spi_device->id, spi_device->mode);
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_SUSPEND:
|
||||
SPI_Disable(spi_device->id, spi_device->mode);
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_CONFIG /* constant-expression */:
|
||||
/* code */
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_ATTACH_TX_DMA /* constant-expression */:
|
||||
spi_device->tx_dma = (struct device *)args;
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_ATTACH_RX_DMA /* constant-expression */:
|
||||
spi_device->rx_dma = (struct device *)args;
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_SPI_CONFIG_CLOCK /* constant-expression */:
|
||||
SPI_SetClock(spi_device->id, (uint32_t)args);
|
||||
break;
|
||||
|
||||
case DEVICE_CTRL_TX_DMA_SUSPEND: {
|
||||
uint32_t tmpVal = BL_RD_REG(SPI_BASE + spi_device->id * 0x100, SPI_FIFO_CONFIG_0);
|
||||
tmpVal = BL_CLR_REG_BIT(tmpVal, SPI_DMA_TX_EN);
|
||||
BL_WR_REG(SPI_BASE + spi_device->id * 0x100, SPI_FIFO_CONFIG_0, tmpVal);
|
||||
dev->oflag &= ~DEVICE_OFLAG_DMA_TX;
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_CTRL_RX_DMA_SUSPEND: {
|
||||
uint32_t tmpVal = BL_RD_REG(SPI_BASE + spi_device->id * 0x100, SPI_FIFO_CONFIG_0);
|
||||
tmpVal = BL_CLR_REG_BIT(tmpVal, SPI_DMA_RX_EN);
|
||||
BL_WR_REG(SPI_BASE + spi_device->id * 0x100, SPI_FIFO_CONFIG_0, tmpVal);
|
||||
dev->oflag &= ~DEVICE_OFLAG_DMA_RX;
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_CTRL_TX_DMA_RESUME: {
|
||||
uint32_t tmpVal = BL_RD_REG(SPI_BASE + spi_device->id * 0x100, SPI_FIFO_CONFIG_0);
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, SPI_DMA_TX_EN);
|
||||
BL_WR_REG(SPI_BASE + spi_device->id * 0x100, SPI_FIFO_CONFIG_0, tmpVal);
|
||||
dev->oflag |= DEVICE_OFLAG_DMA_TX;
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_CTRL_RX_DMA_RESUME: {
|
||||
uint32_t tmpVal = BL_RD_REG(SPI_BASE + spi_device->id * 0x100, SPI_FIFO_CONFIG_0);
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, SPI_DMA_RX_EN);
|
||||
BL_WR_REG(SPI_BASE + spi_device->id * 0x100, SPI_FIFO_CONFIG_0, tmpVal);
|
||||
dev->oflag |= DEVICE_OFLAG_DMA_RX;
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_CTRL_SPI_GET_TX_FIFO :
|
||||
return SPI_GetTxFifoCount(spi_device->id);
|
||||
|
||||
case DEVICE_CTRL_SPI_GET_RX_FIFO :
|
||||
return SPI_GetRxFifoCount(spi_device->id);
|
||||
|
||||
case DEVICE_CTRL_SPI_CLEAR_TX_FIFO :
|
||||
return SPI_ClrTxFifo(spi_device->id);
|
||||
|
||||
case DEVICE_CTRL_SPI_CLEAR_RX_FIFO :
|
||||
return SPI_ClrRxFifo(spi_device->id);
|
||||
|
||||
case DEVICE_CTRL_SPI_GET_BUS_BUSY_STATUS :
|
||||
return SPI_GetBusyStatus(spi_device->id);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @param pos
|
||||
* @param buffer
|
||||
* @param size
|
||||
* @return int
|
||||
*/
|
||||
int spi_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
spi_device_t *spi_device = (spi_device_t *)dev;
|
||||
|
||||
if (dev->oflag & DEVICE_OFLAG_DMA_TX) {
|
||||
struct device *dma_ch = (struct device *)spi_device->tx_dma;
|
||||
|
||||
if (!dma_ch) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (spi_device->id == 0) {
|
||||
/* Set valid width for each fifo entry */
|
||||
uint32_t tmpVal;
|
||||
uint32_t SPIx = SPI_BASE;
|
||||
tmpVal = BL_RD_REG(SPIx, SPI_CONFIG);
|
||||
switch (DMA_DEV(dma_ch)->dst_width) {
|
||||
case DMA_TRANSFER_WIDTH_8BIT:
|
||||
BL_WR_REG(SPIx, SPI_CONFIG, BL_SET_REG_BITS_VAL(tmpVal, SPI_CR_SPI_FRAME_SIZE, 0));
|
||||
break;
|
||||
case DMA_TRANSFER_WIDTH_16BIT:
|
||||
BL_WR_REG(SPIx, SPI_CONFIG, BL_SET_REG_BITS_VAL(tmpVal, SPI_CR_SPI_FRAME_SIZE, 1));
|
||||
break;
|
||||
|
||||
case DMA_TRANSFER_WIDTH_32BIT:
|
||||
BL_WR_REG(SPIx, SPI_CONFIG, BL_SET_REG_BITS_VAL(tmpVal, SPI_CR_SPI_FRAME_SIZE, 3));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret = dma_reload(dma_ch, (uint32_t)buffer, (uint32_t)DMA_ADDR_SPI_TDR, size);
|
||||
dma_channel_start(dma_ch);
|
||||
}
|
||||
return ret;
|
||||
} else if (dev->oflag & DEVICE_OFLAG_INT_TX) {
|
||||
return -2;
|
||||
} else {
|
||||
if (spi_device->datasize == SPI_DATASIZE_8BIT) {
|
||||
return SPI_Send_8bits(spi_device->id, (uint8_t *)buffer, size, SPI_TIMEOUT_DISABLE);
|
||||
} else if (spi_device->datasize == SPI_DATASIZE_16BIT) {
|
||||
return SPI_Send_16bits(spi_device->id, (uint16_t *)buffer, size, SPI_TIMEOUT_DISABLE);
|
||||
} else if (spi_device->datasize == SPI_DATASIZE_24BIT) {
|
||||
return SPI_Send_24bits(spi_device->id, (uint32_t *)buffer, size, SPI_TIMEOUT_DISABLE);
|
||||
} else {
|
||||
return SPI_Send_32bits(spi_device->id, (uint32_t *)buffer, size, SPI_TIMEOUT_DISABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @param pos
|
||||
* @param buffer
|
||||
* @param size
|
||||
* @return int
|
||||
*/
|
||||
int spi_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
spi_device_t *spi_device = (spi_device_t *)dev;
|
||||
|
||||
if (dev->oflag & DEVICE_OFLAG_DMA_RX) {
|
||||
struct device *dma_ch = (struct device *)spi_device->rx_dma;
|
||||
|
||||
if (!dma_ch) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (spi_device->id == 0) {
|
||||
/* Set valid width for each fifo entry */
|
||||
uint32_t tmpVal;
|
||||
uint32_t SPIx = SPI_BASE;
|
||||
tmpVal = BL_RD_REG(SPIx, SPI_CONFIG);
|
||||
switch (DMA_DEV(dma_ch)->src_width) {
|
||||
case DMA_TRANSFER_WIDTH_8BIT:
|
||||
BL_WR_REG(SPIx, SPI_CONFIG, BL_SET_REG_BITS_VAL(tmpVal, SPI_CR_SPI_FRAME_SIZE, 0));
|
||||
break;
|
||||
case DMA_TRANSFER_WIDTH_16BIT:
|
||||
BL_WR_REG(SPIx, SPI_CONFIG, BL_SET_REG_BITS_VAL(tmpVal, SPI_CR_SPI_FRAME_SIZE, 1));
|
||||
break;
|
||||
|
||||
case DMA_TRANSFER_WIDTH_32BIT:
|
||||
BL_WR_REG(SPIx, SPI_CONFIG, BL_SET_REG_BITS_VAL(tmpVal, SPI_CR_SPI_FRAME_SIZE, 3));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ret = dma_reload(dma_ch, (uint32_t)DMA_ADDR_SPI_RDR, (uint32_t)buffer, size);
|
||||
dma_channel_start(dma_ch);
|
||||
}
|
||||
return ret;
|
||||
} else if (dev->oflag & DEVICE_OFLAG_INT_TX) {
|
||||
return -2;
|
||||
} else {
|
||||
if (spi_device->datasize == SPI_DATASIZE_8BIT) {
|
||||
return SPI_Recv_8bits(spi_device->id, (uint8_t *)buffer, size, SPI_TIMEOUT_DISABLE);
|
||||
} else if (spi_device->datasize == SPI_DATASIZE_16BIT) {
|
||||
return SPI_Recv_16bits(spi_device->id, (uint16_t *)buffer, size, SPI_TIMEOUT_DISABLE);
|
||||
} else if (spi_device->datasize == SPI_DATASIZE_24BIT) {
|
||||
return SPI_Recv_24bits(spi_device->id, (uint32_t *)buffer, size, SPI_TIMEOUT_DISABLE);
|
||||
} else {
|
||||
return SPI_Recv_32bits(spi_device->id, (uint32_t *)buffer, size, SPI_TIMEOUT_DISABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param index
|
||||
* @param name
|
||||
* @param flag
|
||||
* @return int
|
||||
*/
|
||||
int spi_register(enum spi_index_type index, const char *name)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
if (SPI_MAX_INDEX == 0) {
|
||||
return -DEVICE_EINVAL;
|
||||
}
|
||||
|
||||
dev = &(spix_device[index].parent);
|
||||
|
||||
dev->open = spi_open;
|
||||
dev->close = spi_close;
|
||||
dev->control = spi_control;
|
||||
dev->write = spi_write;
|
||||
dev->read = spi_read;
|
||||
|
||||
dev->type = DEVICE_CLASS_SPI;
|
||||
dev->handle = NULL;
|
||||
|
||||
return device_register(dev, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @param buffer
|
||||
* @param size
|
||||
* @param type
|
||||
* @return int
|
||||
*/
|
||||
int spi_transmit(struct device *dev, void *buffer, uint32_t size, uint8_t type)
|
||||
{
|
||||
spi_device_t *spi_device = (spi_device_t *)dev;
|
||||
|
||||
if (type == 0) {
|
||||
return SPI_Send_8bits(spi_device->id, (uint8_t *)buffer, size, SPI_TIMEOUT_DISABLE);
|
||||
} else if (type == 1) {
|
||||
return SPI_Send_16bits(spi_device->id, (uint16_t *)buffer, size, SPI_TIMEOUT_DISABLE);
|
||||
} else if (type == 2) {
|
||||
return SPI_Send_24bits(spi_device->id, (uint32_t *)buffer, size, SPI_TIMEOUT_DISABLE);
|
||||
} else if (type == 3) {
|
||||
return SPI_Send_32bits(spi_device->id, (uint32_t *)buffer, size, SPI_TIMEOUT_DISABLE);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @param buffer
|
||||
* @param size
|
||||
* @param type
|
||||
* @return int
|
||||
*/
|
||||
int spi_receive(struct device *dev, void *buffer, uint32_t size, uint8_t type)
|
||||
{
|
||||
spi_device_t *spi_device = (spi_device_t *)dev;
|
||||
|
||||
if (type == 0) {
|
||||
return SPI_Recv_8bits(spi_device->id, (uint8_t *)buffer, size, SPI_TIMEOUT_DISABLE);
|
||||
} else if (type == 1) {
|
||||
return SPI_Recv_16bits(spi_device->id, (uint16_t *)buffer, size, SPI_TIMEOUT_DISABLE);
|
||||
} else if (type == 2) {
|
||||
return SPI_Recv_24bits(spi_device->id, (uint32_t *)buffer, size, SPI_TIMEOUT_DISABLE);
|
||||
} else if (type == 3) {
|
||||
return SPI_Recv_32bits(spi_device->id, (uint32_t *)buffer, size, SPI_TIMEOUT_DISABLE);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @param send_buf
|
||||
* @param recv_buf
|
||||
* @param length
|
||||
* @param type
|
||||
* @return int
|
||||
*/
|
||||
int spi_transmit_receive(struct device *dev, const void *send_buf, void *recv_buf, uint32_t length, uint8_t type)
|
||||
{
|
||||
spi_device_t *spi_device = (spi_device_t *)dev;
|
||||
|
||||
if (type == 0) {
|
||||
return SPI_SendRecv_8bits(spi_device->id, (uint8_t *)send_buf, (uint8_t *)recv_buf, length, SPI_TIMEOUT_DISABLE);
|
||||
} else if (type == 1) {
|
||||
return SPI_SendRecv_16bits(spi_device->id, (uint16_t *)send_buf, (uint16_t *)recv_buf, length, SPI_TIMEOUT_DISABLE);
|
||||
} else if (type == 2) {
|
||||
return SPI_SendRecv_24bits(spi_device->id, (uint32_t *)send_buf, (uint32_t *)recv_buf, length, SPI_TIMEOUT_DISABLE);
|
||||
} else if (type == 3) {
|
||||
return SPI_SendRecv_32bits(spi_device->id, (uint32_t *)send_buf, (uint32_t *)recv_buf, length, SPI_TIMEOUT_DISABLE);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param handle
|
||||
*/
|
||||
void spi_isr(spi_device_t *handle)
|
||||
{
|
||||
uint32_t tmpVal;
|
||||
uint32_t SPIx = SPI_BASE + handle->id * 0x100;
|
||||
|
||||
tmpVal = BL_RD_REG(SPIx, SPI_INT_STS);
|
||||
|
||||
if (!handle->parent.callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Transfer end interrupt,shared by both master and slave mode */
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, SPI_END_INT) && !BL_IS_REG_BIT_SET(tmpVal, SPI_CR_SPI_END_MASK)) {
|
||||
BL_WR_REG(SPIx, SPI_INT_STS, BL_SET_REG_BIT(tmpVal, SPI_CR_SPI_END_CLR));
|
||||
handle->parent.callback(&handle->parent, NULL, 0, SPI_INT_END);
|
||||
}
|
||||
|
||||
/* TX fifo ready interrupt(fifo count > fifo threshold) */
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, SPI_TXF_INT) && !BL_IS_REG_BIT_SET(tmpVal, SPI_CR_SPI_TXF_MASK)) {
|
||||
handle->parent.callback(&handle->parent, NULL, 0, SPI_INT_TX_FIFO_REQ);
|
||||
}
|
||||
|
||||
/* RX fifo ready interrupt(fifo count > fifo threshold) */
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, SPI_RXF_INT) && !BL_IS_REG_BIT_SET(tmpVal, SPI_CR_SPI_RXF_MASK)) {
|
||||
handle->parent.callback(&handle->parent, NULL, 0, SPI_INT_RX_FIFO_REQ);
|
||||
}
|
||||
|
||||
/* Slave mode transfer time-out interrupt,triggered when bus is idle for the given value */
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, SPI_STO_INT) && !BL_IS_REG_BIT_SET(tmpVal, SPI_CR_SPI_STO_MASK)) {
|
||||
BL_WR_REG(SPIx, SPI_INT_STS, BL_SET_REG_BIT(tmpVal, SPI_CR_SPI_STO_CLR));
|
||||
handle->parent.callback(&handle->parent, NULL, 0, SPI_INT_SLAVE_TIMEOUT);
|
||||
}
|
||||
|
||||
/* Slave mode tx underrun error interrupt,trigged when tx is not ready during transfer */
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, SPI_TXU_INT) && !BL_IS_REG_BIT_SET(tmpVal, SPI_CR_SPI_TXU_MASK)) {
|
||||
BL_WR_REG(SPIx, SPI_INT_STS, BL_SET_REG_BIT(tmpVal, SPI_CR_SPI_TXU_CLR));
|
||||
handle->parent.callback(&handle->parent, NULL, 0, SPI_INT_SLAVE_UNDERRUN);
|
||||
}
|
||||
|
||||
/* TX/RX fifo overflow/underflow interrupt */
|
||||
if (BL_IS_REG_BIT_SET(tmpVal, SPI_FER_INT) && !BL_IS_REG_BIT_SET(tmpVal, SPI_CR_SPI_FER_MASK)) {
|
||||
handle->parent.callback(&handle->parent, NULL, 0, SPI_INT_FIFO_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BSP_USING_SPI0
|
||||
void SPI0_IRQ()
|
||||
{
|
||||
spi_isr(&spix_device[SPI0_INDEX]);
|
||||
}
|
||||
#endif
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "bflb_platform.h"
|
||||
#include "bl702_config.h"
|
||||
#include "bl702_glb.h"
|
||||
#include "hal_clock.h"
|
||||
#include "hal_gpio.h"
|
||||
|
||||
struct pin_mux_cfg {
|
||||
|
||||
@@ -798,15 +798,8 @@ void showDebugMenu(void) {
|
||||
}
|
||||
|
||||
void showWarnings() {
|
||||
// MSG((char *)"showWarningsshowWarnings\r\n");
|
||||
return; // TODO remove this patch
|
||||
// Display alert if settings were reset
|
||||
if (settingsWereReset) {
|
||||
// MSG((char *)"WarnUser - %ld\r\n\r\n", (uint64_t)Tr);
|
||||
// MSG((char *)"WarnUser - %ld\r\n\r\n", (uint64_t)Tr);
|
||||
// MSG((char *)"WarnUser - %ld\r\n\r\n", (uint64_t)Tr);
|
||||
// MSG((char *)"WarnUser - %ld\r\n\r\n", (uint64_t)Tr);
|
||||
// MSG((char *)"WarnUser - %ld\r\n\r\n", (uint64_t)Tr);
|
||||
|
||||
warnUser(translatedString(Tr->SettingsResetMessage), 10 * TICKS_SECOND);
|
||||
}
|
||||
@@ -815,7 +808,6 @@ void showWarnings() {
|
||||
// In this case though, we dont want to nag the user _too_ much
|
||||
// So only show first 2 times
|
||||
while (DetectedAccelerometerVersion == AccelType::Scanning) {
|
||||
// MSG((char *)"Accel Detect");
|
||||
osDelay(5);
|
||||
}
|
||||
// Display alert if accelerometer is not detected
|
||||
@@ -845,14 +837,10 @@ uint8_t disconnectedTipF[sizeof(disconnectedTip)];
|
||||
/* StartGUITask function */
|
||||
void startGUITask(void const *argument) {
|
||||
(void)argument;
|
||||
// MSG((char *)"startGUITask\r\n");
|
||||
prepareTranslations();
|
||||
// MSG((char *)"OLEDInit\r\n");
|
||||
|
||||
OLED::initialize(); // start up the LCD
|
||||
// MSG((char *)"setBrightness\r\n");
|
||||
OLED::setBrightness(getSettingValue(SettingsOptions::OLEDBrightness));
|
||||
// MSG((char *)"setInverseDisplay\r\n");
|
||||
OLED::setInverseDisplay(getSettingValue(SettingsOptions::OLEDInversion));
|
||||
|
||||
uint8_t tempWarningState = 0;
|
||||
@@ -860,7 +848,6 @@ void startGUITask(void const *argument) {
|
||||
bool tempOnDisplay = false;
|
||||
bool tipDisconnectedDisplay = false;
|
||||
bool showExitMenuTransition = false;
|
||||
// MSG((char *)"flip\r\n");
|
||||
|
||||
{
|
||||
// Generate the flipped screen into ram for later use
|
||||
@@ -873,24 +860,18 @@ void startGUITask(void const *argument) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// MSG((char *)"tipTemp\r\n");
|
||||
|
||||
getTipRawTemp(1); // reset filter
|
||||
// MSG((char *)"setRotation\r\n");
|
||||
|
||||
OLED::setRotation(getSettingValue(SettingsOptions::OrientationMode) & 1);
|
||||
// MSG((char *)"Bootlogo\r\n");
|
||||
|
||||
// BootLogo::handleShowingLogo((uint8_t *)FLASH_LOGOADDR);
|
||||
// MSG((char *)"showWarnings\r\n");
|
||||
showWarnings();
|
||||
// MSG((char *)"AutoStartMode\r\n");
|
||||
if (getSettingValue(SettingsOptions::AutoStartMode)) {
|
||||
// jump directly to the autostart mode
|
||||
gui_solderingMode(getSettingValue(SettingsOptions::AutoStartMode) - 1);
|
||||
buttonLockout = true;
|
||||
}
|
||||
// MSG((char *)"GUI Thread Start\r\n");
|
||||
|
||||
for (;;) {
|
||||
ButtonState buttons = getButtonState();
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
// Small worker thread to handle power (PD + QC) related steps
|
||||
|
||||
void startPOWTask(void const *argument __unused) {
|
||||
// MSG((char *)"startPOWTask\r\n");
|
||||
// Init any other misc sensors
|
||||
postRToSInit();
|
||||
// You have to run this once we are willing to answer PD messages
|
||||
@@ -41,24 +40,19 @@ void startPOWTask(void const *argument __unused) {
|
||||
* Then Good CRC is set while reading it out (racing on I2C read)
|
||||
* Then we would sleep as nothing to do, but 100ms> 20ms power supply typical timeout
|
||||
*/
|
||||
// MSG((char *)"getFUS302IRQLow\r\n");
|
||||
if (!getFUS302IRQLow()) {
|
||||
res = xTaskNotifyWait(0x0, 0xFFFFFF, NULL, TICKS_100MS);
|
||||
}
|
||||
|
||||
#if POW_PD
|
||||
// MSG((char *)"IRQ\r\n");
|
||||
if (res != pdFALSE || getFUS302IRQLow()) {
|
||||
USBPowerDelivery::IRQOccured();
|
||||
}
|
||||
// MSG((char *)"Step\r\n");
|
||||
USBPowerDelivery::step();
|
||||
// MSG((char *)"PPS\r\n");
|
||||
USBPowerDelivery::PPSTimerCallback();
|
||||
#else
|
||||
(void)res;
|
||||
#endif
|
||||
// MSG((char *)"power_check\r\n");
|
||||
power_check();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user