1
0
forked from me/IronOS

[Squash] Move I2C to IRQ based for big txn

Squash DMA attempt out

.
This commit is contained in:
Ben V. Brown
2025-02-21 18:42:17 +11:00
parent c2ec65cafb
commit 48b28123a6
9 changed files with 382 additions and 484 deletions

View File

@@ -7,17 +7,80 @@
#include "BSP.h" #include "BSP.h"
#include "IRQ.h" #include "IRQ.h"
#include "Setup.h" #include "Setup.h"
#include "bl_mcu_sdk/drivers/bl702_driver/std_drv/inc/bl702_dma.h"
extern "C" { extern "C" {
#include "bflb_platform.h" #include "bflb_platform.h"
#include "bl702_dma.h"
#include "bl702_glb.h" #include "bl702_glb.h"
#include "bl702_i2c.h" #include "bl702_i2c.h"
} }
#include <I2C_Wrapper.hpp> #include <I2C_Wrapper.hpp>
// Semaphore for locking users of I2C
SemaphoreHandle_t FRToSI2C::I2CSemaphore = nullptr; SemaphoreHandle_t FRToSI2C::I2CSemaphore = nullptr;
StaticSemaphore_t FRToSI2C::xSemaphoreBuffer; StaticSemaphore_t FRToSI2C::xSemaphoreBuffer;
#define I2C_TIME_OUT (uint16_t)(12000) #define I2C_TIME_OUT (uint16_t)(12000)
void FRToSI2C::CpltCallback() {} // Not used #define I2C_TX_FIFO_ADDR (0x4000A300 + 0x88)
// Used by the irq handler
volatile uint8_t *irq_data_ptr;
volatile uint8_t irq_data_size_left;
/****** IRQ Handlers ******/
void i2c_irq_tx_fifo_low() {
// Filling tx fifo
// Fifo is 32 bit, LSB sent first
// FiFo can store up to 2, 32-bit words
// So we fill it until it has no free room (or we run out of data)
while (irq_data_size_left > 0 && I2C_GetTXFIFOAvailable() > 0) {
// Can put in at least 1 byte
// Build a 32-bit word from bytes
uint32_t value = 0;
for (int i = 0; i < 4 && irq_data_size_left > 0; i++) {
value >>= 8;
value |= (*irq_data_ptr) << 24; // Shift to the left, adding new data to the higher byte
irq_data_ptr++; // Shift to next byte
irq_data_size_left--;
}
// Push the new value to the fifo
*((volatile uint32_t *)I2C_TX_FIFO_ADDR) = value;
}
if (irq_data_size_left == 0) {
// Disable IRQ, were done
I2C_IntMask(I2C0_ID, I2C_TX_FIFO_READY_INT, MASK);
}
}
void i2c_irq_done() {
// Mask IRQ's back off
I2C_IntMask(I2C0_ID, I2C_TRANS_END_INT, MASK);
I2C_IntMask(I2C0_ID, I2C_NACK_RECV_INT, MASK);
FRToSI2C::CpltCallback(); // Causes the lock to be released
}
void i2c_irq_nack() {
// Mask IRQ's back off
I2C_IntMask(I2C0_ID, I2C_TRANS_END_INT, MASK);
I2C_IntMask(I2C0_ID, I2C_NACK_RECV_INT, MASK);
FRToSI2C::CpltCallback(); // Causes the lock to be released
}
/****** END IRQ Handlers ******/
void FRToSI2C::CpltCallback() {
// This is only triggered from IRQ context
I2C_Disable(I2C0_ID); // Disable I2C to tidy up
// Unlock the semaphore && allow task switch if desired by RTOS
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(I2CSemaphore, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
bool FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) { return Mem_Write(address, reg, &data, 1); } bool FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) { return Mem_Write(address, reg, &data, 1); }
@@ -56,6 +119,7 @@ bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *p_bu
if (!lock()) { if (!lock()) {
return false; return false;
} }
I2C_Transfer_Cfg i2cCfg = {0, DISABLE, 0, 0, 0, 0}; I2C_Transfer_Cfg i2cCfg = {0, DISABLE, 0, 0, 0, 0};
BL_Err_Type err = ERROR; BL_Err_Type err = ERROR;
i2cCfg.slaveAddr = DevAddress >> 1; i2cCfg.slaveAddr = DevAddress >> 1;
@@ -65,16 +129,36 @@ bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *p_bu
i2cCfg.data = p_buffer; i2cCfg.data = p_buffer;
i2cCfg.subAddrSize = 1; // one byte address i2cCfg.subAddrSize = 1; // one byte address
vTaskSuspendAll(); if (number_of_byte <= 32) {
/* --------------- */ vTaskSuspendAll();
err = I2C_MasterSendBlocking(I2C0_ID, &i2cCfg); /* --------------- */
xTaskResumeAll(); err = I2C_MasterSendBlocking(I2C0_ID, &i2cCfg);
bool res = err == SUCCESS; xTaskResumeAll();
if (!res) { bool res = err == SUCCESS;
I2C_Unstick(); if (!res) {
I2C_Unstick();
}
unlock();
return res;
} else {
// Store handles for IRQ
irq_data_ptr = p_buffer;
irq_data_size_left = number_of_byte;
// Setup and run
I2C_Init(I2C0_ID, I2C_WRITE, &i2cCfg); // Setup hardware for the I2C init header with the device address
I2C_IntMask(I2C0_ID, I2C_TRANS_END_INT, UNMASK);
I2C_IntMask(I2C0_ID, I2C_NACK_RECV_INT, UNMASK);
I2C_IntMask(I2C0_ID, I2C_TX_FIFO_READY_INT, UNMASK);
I2C_Int_Callback_Install(I2C0_ID, I2C_TRANS_END_INT, i2c_irq_done);
I2C_Int_Callback_Install(I2C0_ID, I2C_NACK_RECV_INT, i2c_irq_nack);
I2C_Int_Callback_Install(I2C0_ID, I2C_TX_FIFO_READY_INT, i2c_irq_tx_fifo_low);
i2c_irq_tx_fifo_low(); // Pre-fill fifo
// Start
I2C_Enable(I2C0_ID);
// Dont unlock as tx is still ongoing, will be cleared in irq of i2c finishing
return true;
} }
unlock();
return res;
} }
bool FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) { return Mem_Write(DevAddress, pData[0], pData + 1, Size - 1); } bool FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) { return Mem_Write(DevAddress, pData[0], pData + 1, Size - 1); }

View File

@@ -10,6 +10,7 @@
#include "FreeRTOSConfig.h" #include "FreeRTOSConfig.h"
#include "IRQ.h" #include "IRQ.h"
#include "Pins.h" #include "Pins.h"
#include "bl702_dma.h"
#include "bl702_sec_eng.h" #include "bl702_sec_eng.h"
#include "history.hpp" #include "history.hpp"
#include <string.h> #include <string.h>
@@ -66,7 +67,10 @@ void hardware_init() {
I2C_SetDeglitchCount(I2C0_ID, 1); // Turn on de-glitch I2C_SetDeglitchCount(I2C0_ID, 1); // Turn on de-glitch
// Note on I2C clock rate @ 100Khz the screen update == 20ms which is too long for USB-PD to work // Note on I2C clock rate @ 100Khz the screen update == 20ms which is too long for USB-PD to work
// 200kHz and above works // 200kHz and above works
I2C_ClockSet(I2C0_ID, 300000); // Sets clock to around 25 kHz less than set here I2C_ClockSet(I2C0_ID, 300000); // Sets clock to around 25 kHz less than set here
CPU_Interrupt_Enable(I2C_IRQn);
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_0, 0); TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_0, 0);
} }
void setup_pwm(void) { void setup_pwm(void) {

View File

@@ -92,8 +92,8 @@ int dma_open(struct device *dev, uint16_t oflag) {
chCfg.dstPeriph = dma_device->dst_req; chCfg.dstPeriph = dma_device->dst_req;
chCfg.srcAddrInc = dma_device->src_addr_inc; chCfg.srcAddrInc = dma_device->src_addr_inc;
chCfg.destAddrInc = dma_device->dst_addr_inc; chCfg.destAddrInc = dma_device->dst_addr_inc;
chCfg.srcBurstSzie = dma_device->src_burst_size; chCfg.srcBurstSize = dma_device->src_burst_size;
chCfg.dstBurstSzie = dma_device->dst_burst_size; chCfg.dstBurstSize = dma_device->dst_burst_size;
chCfg.srcTransfWidth = dma_device->src_width; chCfg.srcTransfWidth = dma_device->src_width;
chCfg.dstTransfWidth = dma_device->dst_width; chCfg.dstTransfWidth = dma_device->dst_width;
DMA_Channel_Init(&chCfg); DMA_Channel_Init(&chCfg);

View File

@@ -39,6 +39,10 @@
#include "dma_reg.h" #include "dma_reg.h"
#include "bl702_common.h" #include "bl702_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup BL702_Peripheral_Driver /** @addtogroup BL702_Peripheral_Driver
* @{ * @{
*/ */
@@ -168,9 +172,9 @@ typedef struct
DMA_Chan_Type ch; /*!< Channel select 0-7 */ DMA_Chan_Type ch; /*!< Channel select 0-7 */
DMA_Trans_Width_Type srcTransfWidth; /*!< Transfer width. 0: 8 bits, 1: 16 bits, 2: 32 bits */ DMA_Trans_Width_Type srcTransfWidth; /*!< Transfer width. 0: 8 bits, 1: 16 bits, 2: 32 bits */
DMA_Trans_Width_Type dstTransfWidth; /*!< Transfer width. 0: 8 bits, 1: 16 bits, 2: 32 bits */ DMA_Trans_Width_Type dstTransfWidth; /*!< Transfer width. 0: 8 bits, 1: 16 bits, 2: 32 bits */
DMA_Burst_Size_Type srcBurstSzie; /*!< Number of data items for burst transaction length. Each item width is as same as tansfer width. DMA_Burst_Size_Type srcBurstSize; /*!< Number of data items for burst transaction length. Each item width is as same as tansfer width.
0: 1 item, 1: 4 items, 2: 8 items, 3: 16 items */ 0: 1 item, 1: 4 items, 2: 8 items, 3: 16 items */
DMA_Burst_Size_Type dstBurstSzie; /*!< Number of data items for burst transaction length. Each item width is as same as tansfer width. DMA_Burst_Size_Type dstBurstSize; /*!< Number of data items for burst transaction length. Each item width is as same as tansfer width.
0: 1 item, 1: 4 items, 2: 8 items, 3: 16 items */ 0: 1 item, 1: 4 items, 2: 8 items, 3: 16 items */
BL_Fun_Type dstAddMode; /*!< */ BL_Fun_Type dstAddMode; /*!< */
BL_Fun_Type dstMinMode; /*!< */ BL_Fun_Type dstMinMode; /*!< */
@@ -181,16 +185,6 @@ typedef struct
DMA_Periph_Req_Type dstPeriph; /*!< Destination peripheral select */ DMA_Periph_Req_Type dstPeriph; /*!< Destination peripheral select */
} DMA_Channel_Cfg_Type; } DMA_Channel_Cfg_Type;
/**
* @brief DMA LLI control structure type definition
*/
typedef struct
{
uint32_t srcDmaAddr; /*!< Source address of DMA transfer */
uint32_t destDmaAddr; /*!< Destination address of DMA transfer */
uint32_t nextLLI; /*!< Next LLI address */
struct DMA_Control_Reg dmaCtrl; /*!< DMA transaction control */
} DMA_LLI_Ctrl_Type;
/** /**
* @brief DMA LLI configuration structure type definition * @brief DMA LLI configuration structure type definition
@@ -202,31 +196,6 @@ typedef struct
DMA_Periph_Req_Type dstPeriph; /*!< Destination peripheral select */ DMA_Periph_Req_Type dstPeriph; /*!< Destination peripheral select */
} DMA_LLI_Cfg_Type; } DMA_LLI_Cfg_Type;
/**
* @brief DMA LLI Ping-Pong Buf definition
*/
typedef struct
{
uint8_t idleIndex; /*!< Index Idle lliListHeader */
uint8_t dmaChan; /*!< DMA LLI Channel used */
DMA_LLI_Ctrl_Type *lliListHeader[2]; /*!< Ping-Pong BUf List Header */
void (*onTransCompleted)(DMA_LLI_Ctrl_Type *); /*!< Completed Transmit One List Callback Function */
} DMA_LLI_PP_Buf;
/**
* @brief DMA LLI Ping-Pong Structure definition
*/
typedef struct
{
uint8_t trans_index; /*!< Ping or Pong Trigger TC */
uint8_t dmaChan; /*!< DMA LLI Channel used */
struct DMA_Control_Reg dmaCtrlRegVal; /*!< DMA Basic Pararmeter */
DMA_LLI_Cfg_Type *DMA_LLI_Cfg; /*!< LLI Config parameter */
uint32_t operatePeriphAddr; /*!< Operate Peripheral register address */
uint32_t chache_buf_addr[2]; /*!< Ping-Pong structure chache */
BL_Fun_Type is_single_mode; /*!< is Ping-pong running forever or single mode ,if is single mode ping-pong will run only once
after one start */
} DMA_LLI_PP_Struct;
/*@} end of group DMA_Public_Types */ /*@} end of group DMA_Public_Types */
@@ -346,16 +315,7 @@ void DMA_Channel_Disable(uint8_t ch);
void DMA_LLI_Init(uint8_t ch, DMA_LLI_Cfg_Type *lliCfg); void DMA_LLI_Init(uint8_t ch, DMA_LLI_Cfg_Type *lliCfg);
void DMA_LLI_Update(uint8_t ch, uint32_t LLI); void DMA_LLI_Update(uint8_t ch, uint32_t LLI);
void DMA_IntMask(uint8_t ch, DMA_INT_Type intType, BL_Mask_Type intMask); void DMA_IntMask(uint8_t ch, DMA_INT_Type intType, BL_Mask_Type intMask);
void DMA_LLI_PpBuf_Start_New_Transmit(DMA_LLI_PP_Buf *dmaPpBuf);
DMA_LLI_Ctrl_Type *DMA_LLI_PpBuf_Remove_Completed_List(DMA_LLI_PP_Buf *dmaPpBuf);
void DMA_LLI_PpBuf_Append(DMA_LLI_PP_Buf *dmaPpBuf, DMA_LLI_Ctrl_Type *dmaLliList);
void DMA_LLI_PpBuf_Destroy(DMA_LLI_PP_Buf *dmaPpBuf);
void DMA_Int_Callback_Install(DMA_Chan_Type dmaChan, DMA_INT_Type intType, intCallback_Type *cbFun); void DMA_Int_Callback_Install(DMA_Chan_Type dmaChan, DMA_INT_Type intType, intCallback_Type *cbFun);
void DMA_LLI_PpStruct_Start(DMA_LLI_PP_Struct *dmaPpStruct);
void DMA_LLI_PpStruct_Stop(DMA_LLI_PP_Struct *dmaPpStruct);
BL_Err_Type DMA_LLI_PpStruct_Init(DMA_LLI_PP_Struct *dmaPpStruct);
BL_Err_Type DMA_LLI_PpStruct_Set_Transfer_Len(DMA_LLI_PP_Struct *dmaPpStruct,
uint16_t Ping_Transfer_len, uint16_t Pong_Transfer_len);
/*@} end of group DMA_Public_Functions */ /*@} end of group DMA_Public_Functions */
@@ -363,4 +323,8 @@ BL_Err_Type DMA_LLI_PpStruct_Set_Transfer_Len(DMA_LLI_PP_Struct *dmaPpStruct,
/*@} end of group BL702_Peripheral_Driver */ /*@} end of group BL702_Peripheral_Driver */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __BL702_DMA_H__ */ #endif /* __BL702_DMA_H__ */

View File

@@ -1,43 +1,43 @@
/** /**
****************************************************************************** ******************************************************************************
* @file bl702_i2c.h * @file bl702_i2c.h
* @version V1.0 * @version V1.0
* @date * @date
* @brief This file is the standard driver header file * @brief This file is the standard driver header file
****************************************************************************** ******************************************************************************
* @attention * @attention
* *
* <h2><center>&copy; COPYRIGHT(c) 2020 Bouffalo Lab</center></h2> * <h2><center>&copy; COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met: * are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* 3. Neither the name of Bouffalo Lab nor the names of its contributors * 3. Neither the name of Bouffalo Lab nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
****************************************************************************** ******************************************************************************
*/ */
#ifndef __BL702_I2C_H__ #ifndef __BL702_I2C_H__
#define __BL702_I2C_H__ #define __BL702_I2C_H__
#include "i2c_reg.h"
#include "bl702_common.h" #include "bl702_common.h"
#include "i2c_reg.h"
/** @addtogroup BL702_Peripheral_Driver /** @addtogroup BL702_Peripheral_Driver
* @{ * @{
@@ -55,75 +55,71 @@
* @brief I2C No. type definition * @brief I2C No. type definition
*/ */
typedef enum { typedef enum {
I2C0_ID = 0, /*!< I2C0 define */ I2C0_ID = 0, /*!< I2C0 define */
I2C_ID_MAX, /*!< I2C max define */ I2C_ID_MAX, /*!< I2C max define */
} I2C_ID_Type; } I2C_ID_Type;
/** /**
* @brief I2C read/write type definition * @brief I2C read/write type definition
*/ */
typedef enum { typedef enum {
I2C_WRITE = 0, /*!< I2C write direction */ I2C_WRITE = 0, /*!< I2C write direction */
I2C_READ, /*!< I2C read direction */ I2C_READ, /*!< I2C read direction */
} I2C_Direction_Type; } I2C_Direction_Type;
/** /**
* @brief I2C interrupt type definition * @brief I2C interrupt type definition
*/ */
typedef enum { typedef enum {
I2C_TRANS_END_INT, /*!< I2C transfer end interrupt */ I2C_TRANS_END_INT, /*!< I2C transfer end interrupt */
I2C_TX_FIFO_READY_INT, /*!< I2C TX fifo ready interrupt */ I2C_TX_FIFO_READY_INT, /*!< I2C TX fifo ready interrupt */
I2C_RX_FIFO_READY_INT, /*!< I2C RX fifo ready interrupt */ I2C_RX_FIFO_READY_INT, /*!< I2C RX fifo ready interrupt */
I2C_NACK_RECV_INT, /*!< I2C nack received interrupt */ I2C_NACK_RECV_INT, /*!< I2C nack received interrupt */
I2C_ARB_LOST_INT, /*!< I2C arbitration lost interrupt */ I2C_ARB_LOST_INT, /*!< I2C arbitration lost interrupt */
I2C_FIFO_ERR_INT, /*!< I2C TX/RX FIFO error interrupt */ I2C_FIFO_ERR_INT, /*!< I2C TX/RX FIFO error interrupt */
I2C_INT_ALL, /*!< I2C interrupt all type */ I2C_INT_ALL, /*!< I2C interrupt all type */
} I2C_INT_Type; } I2C_INT_Type;
/** /**
* @brief I2S start condition phase structure type definition * @brief I2S start condition phase structure type definition
*/ */
typedef struct typedef struct {
{ uint8_t len0; /*!< Length of START condition phase 0 */
uint8_t len0; /*!< Length of START condition phase 0 */ uint8_t len1; /*!< Length of START condition phase 1 */
uint8_t len1; /*!< Length of START condition phase 1 */ uint8_t len2; /*!< Length of START condition phase 2 */
uint8_t len2; /*!< Length of START condition phase 2 */ uint8_t len3; /*!< Length of START condition phase 3 */
uint8_t len3; /*!< Length of START condition phase 3 */
} I2C_Start_Condition_Phase_Type; } I2C_Start_Condition_Phase_Type;
/** /**
* @brief I2S stop condition phase structure type definition * @brief I2S stop condition phase structure type definition
*/ */
typedef struct typedef struct {
{ uint8_t len0; /*!< Length of STOP condition phase 0 */
uint8_t len0; /*!< Length of STOP condition phase 0 */ uint8_t len1; /*!< Length of STOP condition phase 1 */
uint8_t len1; /*!< Length of STOP condition phase 1 */ uint8_t len2; /*!< Length of STOP condition phase 2 */
uint8_t len2; /*!< Length of STOP condition phase 2 */ uint8_t len3; /*!< Length of STOP condition phase 3 */
uint8_t len3; /*!< Length of STOP condition phase 3 */
} I2C_Stop_Condition_Phase_Type; } I2C_Stop_Condition_Phase_Type;
/** /**
* @brief I2S data phase structure type definition * @brief I2S data phase structure type definition
*/ */
typedef struct typedef struct {
{ uint8_t len0; /*!< Length of DATA phase 0 */
uint8_t len0; /*!< Length of DATA phase 0 */ uint8_t len1; /*!< Length of DATA phase 1 */
uint8_t len1; /*!< Length of DATA phase 1 */ uint8_t len2; /*!< Length of DATA phase 2 */
uint8_t len2; /*!< Length of DATA phase 2 */ uint8_t len3; /*!< Length of DATA phase 3 */
uint8_t len3; /*!< Length of DATA phase 3 */
} I2C_Data_Phase_Type; } I2C_Data_Phase_Type;
/** /**
* @brief I2S transfer structure type definition * @brief I2S transfer structure type definition
*/ */
typedef struct typedef struct {
{ uint8_t slaveAddr; /*!< I2C slave address */
uint8_t slaveAddr; /*!< I2C slave address */ BL_Fun_Type stopEveryByte; /*!< I2C all data byte with stop bit */
BL_Fun_Type stopEveryByte; /*!< I2C all data byte with stop bit */ uint8_t subAddrSize; /*!< Specifies the size of I2C sub address section */
uint8_t subAddrSize; /*!< Specifies the size of I2C sub address section */ uint32_t subAddr; /*!< I2C sub address */
uint32_t subAddr; /*!< I2C sub address */ uint16_t dataSize; /*!< Specifies the size of I2C data section */
uint16_t dataSize; /*!< Specifies the size of I2C data section */ uint8_t *data; /*!< Specifies the pointer of I2C R/W data */
uint8_t *data; /*!< Specifies the pointer of I2C R/W data */
} I2C_Transfer_Cfg; } I2C_Transfer_Cfg;
/*@} end of group I2C_Public_Types */ /*@} end of group I2C_Public_Types */
@@ -135,25 +131,19 @@ typedef struct
/** @defgroup I2C_ID_TYPE /** @defgroup I2C_ID_TYPE
* @{ * @{
*/ */
#define IS_I2C_ID_TYPE(type) (((type) == I2C0_ID) || \ #define IS_I2C_ID_TYPE(type) (((type) == I2C0_ID) || ((type) == I2C_ID_MAX))
((type) == I2C_ID_MAX))
/** @defgroup I2C_DIRECTION_TYPE /** @defgroup I2C_DIRECTION_TYPE
* @{ * @{
*/ */
#define IS_I2C_DIRECTION_TYPE(type) (((type) == I2C_WRITE) || \ #define IS_I2C_DIRECTION_TYPE(type) (((type) == I2C_WRITE) || ((type) == I2C_READ))
((type) == I2C_READ))
/** @defgroup I2C_INT_TYPE /** @defgroup I2C_INT_TYPE
* @{ * @{
*/ */
#define IS_I2C_INT_TYPE(type) (((type) == I2C_TRANS_END_INT) || \ #define IS_I2C_INT_TYPE(type) \
((type) == I2C_TX_FIFO_READY_INT) || \ (((type) == I2C_TRANS_END_INT) || ((type) == I2C_TX_FIFO_READY_INT) || ((type) == I2C_RX_FIFO_READY_INT) || ((type) == I2C_NACK_RECV_INT) || ((type) == I2C_ARB_LOST_INT) || \
((type) == I2C_RX_FIFO_READY_INT) || \ ((type) == I2C_FIFO_ERR_INT) || ((type) == I2C_INT_ALL))
((type) == I2C_NACK_RECV_INT) || \
((type) == I2C_ARB_LOST_INT) || \
((type) == I2C_FIFO_ERR_INT) || \
((type) == I2C_INT_ALL))
/*@} end of group I2C_Public_Constants */ /*@} end of group I2C_Public_Constants */
@@ -173,22 +163,25 @@ typedef struct
#ifndef BFLB_USE_HAL_DRIVER #ifndef BFLB_USE_HAL_DRIVER
void I2C_IRQHandler(void); void I2C_IRQHandler(void);
#endif #endif
void I2C_SendWord(I2C_ID_Type i2cNo, uint32_t data); void I2C_SendWord(I2C_ID_Type i2cNo, uint32_t data);
uint32_t I2C_RecieveWord(I2C_ID_Type i2cNo); uint32_t I2C_RecieveWord(I2C_ID_Type i2cNo);
void I2C_Enable(I2C_ID_Type i2cNo); void I2C_Enable(I2C_ID_Type i2cNo);
void I2C_Disable(I2C_ID_Type i2cNo); void I2C_Disable(I2C_ID_Type i2cNo);
BL_Err_Type I2C_SetDeglitchCount(I2C_ID_Type i2cNo, uint8_t cnt); BL_Err_Type I2C_SetDeglitchCount(I2C_ID_Type i2cNo, uint8_t cnt);
BL_Err_Type I2C_Reset(I2C_ID_Type i2cNo); BL_Err_Type I2C_Reset(I2C_ID_Type i2cNo);
void I2C_SetPrd(I2C_ID_Type i2cNo, uint8_t phase); uint8_t I2C_GetTXFIFOAvailable();
void I2C_ClockSet(I2C_ID_Type i2cNo, uint32_t clk); void I2C_DMATxEnable();
void I2C_SetSclSync(I2C_ID_Type i2cNo, uint8_t enable); void I2C_DMATxDisable();
void I2C_Init(I2C_ID_Type i2cNo, I2C_Direction_Type direct, I2C_Transfer_Cfg *cfg); void I2C_SetPrd(I2C_ID_Type i2cNo, uint8_t phase);
void I2C_ClockSet(I2C_ID_Type i2cNo, uint32_t clk);
void I2C_SetSclSync(I2C_ID_Type i2cNo, uint8_t enable);
void I2C_Init(I2C_ID_Type i2cNo, I2C_Direction_Type direct, I2C_Transfer_Cfg *cfg);
BL_Sts_Type I2C_IsBusy(I2C_ID_Type i2cNo); BL_Sts_Type I2C_IsBusy(I2C_ID_Type i2cNo);
BL_Sts_Type I2C_TransferEndStatus(I2C_ID_Type i2cNo); BL_Sts_Type I2C_TransferEndStatus(I2C_ID_Type i2cNo);
BL_Err_Type I2C_MasterSendBlocking(I2C_ID_Type i2cNo, I2C_Transfer_Cfg *cfg); BL_Err_Type I2C_MasterSendBlocking(I2C_ID_Type i2cNo, I2C_Transfer_Cfg *cfg);
BL_Err_Type I2C_MasterReceiveBlocking(I2C_ID_Type i2cNo, I2C_Transfer_Cfg *cfg); BL_Err_Type I2C_MasterReceiveBlocking(I2C_ID_Type i2cNo, I2C_Transfer_Cfg *cfg);
void I2C_IntMask(I2C_ID_Type i2cNo, I2C_INT_Type intType, BL_Mask_Type intMask); void I2C_IntMask(I2C_ID_Type i2cNo, I2C_INT_Type intType, BL_Mask_Type intMask);
void I2C_Int_Callback_Install(I2C_ID_Type i2cNo, I2C_INT_Type intType, intCallback_Type *cbFun); void I2C_Int_Callback_Install(I2C_ID_Type i2cNo, I2C_INT_Type intType, intCallback_Type *cbFun);
/*@} end of group I2C_Public_Functions */ /*@} end of group I2C_Public_Functions */

View File

@@ -58,7 +58,7 @@ static intCallback_Type *dmaIntCbfArra[DMA_CH_MAX][DMA_INT_ALL] = {
{NULL, NULL}, {NULL, NULL},
{NULL, NULL} {NULL, NULL}
}; };
static DMA_LLI_Ctrl_Type PingPongListArra[DMA_CH_MAX][2]; // static DMA_LLI_Ctrl_Type PingPongListArra[DMA_CH_MAX][2];
/*@} end of group DMA_Private_Macros */ /*@} end of group DMA_Private_Macros */
@@ -90,14 +90,14 @@ static DMA_LLI_Ctrl_Type PingPongListArra[DMA_CH_MAX][2];
* @{ * @{
*/ */
/****************************************************************************/ /** /**
* @brief DMA interrupt handler * @brief DMA interrupt handler
* *
* @param None * @param None
* *
* @return None * @return None
* *
*******************************************************************************/ *******************************************************************************/
#ifndef BFLB_USE_HAL_DRIVER #ifndef BFLB_USE_HAL_DRIVER
void DMA_ALL_IRQHandler(void) { void DMA_ALL_IRQHandler(void) {
uint32_t tmpVal; uint32_t tmpVal;
@@ -150,14 +150,14 @@ void DMA_ALL_IRQHandler(void) {
* @{ * @{
*/ */
/****************************************************************************/ /** /**
* @brief DMA enable * @brief DMA enable
* *
* @param None * @param None
* *
* @return None * @return None
* *
*******************************************************************************/ *******************************************************************************/
void DMA_Enable(void) { void DMA_Enable(void) {
uint32_t tmpVal; uint32_t tmpVal;
/* Get DMA register */ /* Get DMA register */
@@ -171,14 +171,14 @@ void DMA_Enable(void) {
#endif #endif
} }
/****************************************************************************/ /** /**
* @brief DMA disable * @brief DMA disable
* *
* @param None * @param None
* *
* @return None * @return None
* *
*******************************************************************************/ *******************************************************************************/
void DMA_Disable(void) { void DMA_Disable(void) {
uint32_t tmpVal; uint32_t tmpVal;
/* Get DMA register */ /* Get DMA register */
@@ -189,14 +189,14 @@ void DMA_Disable(void) {
BL_WR_REG(DMAChs, DMA_TOP_CONFIG, tmpVal); BL_WR_REG(DMAChs, DMA_TOP_CONFIG, tmpVal);
} }
/****************************************************************************/ /** /**
* @brief DMA channel init * @brief DMA channel init
* *
* @param chCfg: DMA configuration * @param chCfg: DMA configuration
* *
* @return None * @return None
* *
*******************************************************************************/ *******************************************************************************/
void DMA_Channel_Init(DMA_Channel_Cfg_Type *chCfg) { void DMA_Channel_Init(DMA_Channel_Cfg_Type *chCfg) {
uint32_t tmpVal; uint32_t tmpVal;
/* Get channel register */ /* Get channel register */
@@ -206,13 +206,14 @@ void DMA_Channel_Init(DMA_Channel_Cfg_Type *chCfg) {
CHECK_PARAM(IS_DMA_CHAN_TYPE(chCfg->ch)); CHECK_PARAM(IS_DMA_CHAN_TYPE(chCfg->ch));
CHECK_PARAM(IS_DMA_TRANS_WIDTH_TYPE(chCfg->srcTransfWidth)); CHECK_PARAM(IS_DMA_TRANS_WIDTH_TYPE(chCfg->srcTransfWidth));
CHECK_PARAM(IS_DMA_TRANS_WIDTH_TYPE(chCfg->dstTransfWidth)); CHECK_PARAM(IS_DMA_TRANS_WIDTH_TYPE(chCfg->dstTransfWidth));
CHECK_PARAM(IS_DMA_BURST_SIZE_TYPE(chCfg->srcBurstSzie)); CHECK_PARAM(IS_DMA_BURST_SIZE_TYPE(chCfg->srcBurstSize));
CHECK_PARAM(IS_DMA_BURST_SIZE_TYPE(chCfg->dstBurstSzie)); CHECK_PARAM(IS_DMA_BURST_SIZE_TYPE(chCfg->dstBurstSize));
CHECK_PARAM(IS_DMA_TRANS_DIR_TYPE(chCfg->dir)); CHECK_PARAM(IS_DMA_TRANS_DIR_TYPE(chCfg->dir));
CHECK_PARAM(IS_DMA_PERIPH_REQ_TYPE(chCfg->dstPeriph)); CHECK_PARAM(IS_DMA_PERIPH_REQ_TYPE(chCfg->dstPeriph));
CHECK_PARAM(IS_DMA_PERIPH_REQ_TYPE(chCfg->srcPeriph)); CHECK_PARAM(IS_DMA_PERIPH_REQ_TYPE(chCfg->srcPeriph));
/* Disable clock gate */ /* Disable clock gate */
// Turns on clock
GLB_AHB_Slave1_Clock_Gate(DISABLE, BL_AHB_SLAVE1_DMA); GLB_AHB_Slave1_Clock_Gate(DISABLE, BL_AHB_SLAVE1_DMA);
/* Config channel config */ /* Config channel config */
@@ -223,15 +224,15 @@ void DMA_Channel_Init(DMA_Channel_Cfg_Type *chCfg) {
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_TRANSFERSIZE, chCfg->transfLength); tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_TRANSFERSIZE, chCfg->transfLength);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_SWIDTH, chCfg->srcTransfWidth); tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_SWIDTH, chCfg->srcTransfWidth);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_DWIDTH, chCfg->dstTransfWidth); tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_DWIDTH, chCfg->dstTransfWidth);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_SBSIZE, chCfg->srcBurstSzie); tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_SBSIZE, chCfg->srcBurstSize);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_DBSIZE, chCfg->dstBurstSzie); tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_DBSIZE, chCfg->dstBurstSize);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_DST_ADD_MODE, chCfg->dstAddMode); tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_DST_ADD_MODE, chCfg->dstAddMode);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_DST_MIN_MODE, chCfg->dstMinMode); tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_DST_MIN_MODE, chCfg->dstMinMode);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_FIX_CNT, chCfg->fixCnt); tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_FIX_CNT, chCfg->fixCnt);
/* FIXME: how to deal with SLargerD */ /* FIXME: how to deal with SLargerD */
tmpVal = BL_CLR_REG_BIT(tmpVal, DMA_SLARGERD); tmpVal = BL_CLR_REG_BIT(tmpVal, DMA_SLARGERD); // Reserved bit 25
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_SI, chCfg->srcAddrInc); tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_SI, chCfg->srcAddrInc);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_DI, chCfg->destAddrInc); tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_DI, chCfg->destAddrInc);
BL_WR_REG(DMAChs, DMA_CONTROL, tmpVal); BL_WR_REG(DMAChs, DMA_CONTROL, tmpVal);
@@ -241,18 +242,21 @@ void DMA_Channel_Init(DMA_Channel_Cfg_Type *chCfg) {
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_DSTPERIPHERAL, chCfg->dstPeriph); tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_DSTPERIPHERAL, chCfg->dstPeriph);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_SRCPERIPHERAL, chCfg->srcPeriph); tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_SRCPERIPHERAL, chCfg->srcPeriph);
BL_WR_REG(DMAChs, DMA_CONFIG, tmpVal); BL_WR_REG(DMAChs, DMA_CONFIG, tmpVal);
// Clear interrupts
*((uint32_t *)0x4000c008) = 1 << (chCfg->ch); // Clear transfer complete
*((uint32_t *)0x4000c010) = 1 << (chCfg->ch); // Clear Error
} }
/****************************************************************************/ /** /**
* @brief DMA channel update source memory address and len * @brief DMA channel update source memory address and len
* *
* @param ch: DMA channel * @param ch: DMA channel
* @param memAddr: source memoty address * @param memAddr: source memoty address
* @param len: source memory data length * @param len: source memory data length
* *
* @return None * @return None
* *
*******************************************************************************/ *******************************************************************************/
void DMA_Channel_Update_SrcMemcfg(uint8_t ch, uint32_t memAddr, uint32_t len) { void DMA_Channel_Update_SrcMemcfg(uint8_t ch, uint32_t memAddr, uint32_t len) {
uint32_t tmpVal; uint32_t tmpVal;
/* Get channel register */ /* Get channel register */
@@ -268,16 +272,16 @@ void DMA_Channel_Update_SrcMemcfg(uint8_t ch, uint32_t memAddr, uint32_t len) {
BL_WR_REG(DMAChs, DMA_CONTROL, tmpVal); BL_WR_REG(DMAChs, DMA_CONTROL, tmpVal);
} }
/****************************************************************************/ /** /**
* @brief DMA channel update destination memory address and len * @brief DMA channel update destination memory address and len
* *
* @param ch: DMA channel * @param ch: DMA channel
* @param memAddr: destination memoty address * @param memAddr: destination memoty address
* @param len: destination memory data length * @param len: destination memory data length
* *
* @return None * @return None
* *
*******************************************************************************/ *******************************************************************************/
void DMA_Channel_Update_DstMemcfg(uint8_t ch, uint32_t memAddr, uint32_t len) { void DMA_Channel_Update_DstMemcfg(uint8_t ch, uint32_t memAddr, uint32_t len) {
uint32_t tmpVal; uint32_t tmpVal;
/* Get channel register */ /* Get channel register */
@@ -293,14 +297,14 @@ void DMA_Channel_Update_DstMemcfg(uint8_t ch, uint32_t memAddr, uint32_t len) {
BL_WR_REG(DMAChs, DMA_CONTROL, tmpVal); BL_WR_REG(DMAChs, DMA_CONTROL, tmpVal);
} }
/****************************************************************************/ /** /**
* @brief Get DMA channel tranfersize * @brief Get DMA channel tranfersize
* *
* @param ch: DMA channel * @param ch: DMA channel
* *
* @return tranfersize size * @return tranfersize size
* *
*******************************************************************************/ *******************************************************************************/
uint32_t DMA_Channel_TranferSize(uint8_t ch) { uint32_t DMA_Channel_TranferSize(uint8_t ch) {
/* Get channel register */ /* Get channel register */
uint32_t DMAChs = DMA_Get_Channel(ch); uint32_t DMAChs = DMA_Get_Channel(ch);
@@ -311,14 +315,14 @@ uint32_t DMA_Channel_TranferSize(uint8_t ch) {
return BL_GET_REG_BITS_VAL(BL_RD_REG(DMAChs, DMA_CONTROL), DMA_TRANSFERSIZE); return BL_GET_REG_BITS_VAL(BL_RD_REG(DMAChs, DMA_CONTROL), DMA_TRANSFERSIZE);
} }
/****************************************************************************/ /** /**
* @brief Get DMA channel busy status * @brief Get DMA channel busy status
* *
* @param ch: DMA channel * @param ch: DMA channel
* *
* @return SET or RESET * @return SET or RESET
* *
*******************************************************************************/ *******************************************************************************/
BL_Sts_Type DMA_Channel_Is_Busy(uint8_t ch) { BL_Sts_Type DMA_Channel_Is_Busy(uint8_t ch) {
/* Get channel register */ /* Get channel register */
uint32_t DMAChs = DMA_Get_Channel(ch); uint32_t DMAChs = DMA_Get_Channel(ch);
@@ -329,14 +333,14 @@ BL_Sts_Type DMA_Channel_Is_Busy(uint8_t ch) {
return BL_IS_REG_BIT_SET(BL_RD_REG(DMAChs, DMA_CONFIG), DMA_E) == 1 ? SET : RESET; return BL_IS_REG_BIT_SET(BL_RD_REG(DMAChs, DMA_CONFIG), DMA_E) == 1 ? SET : RESET;
} }
/****************************************************************************/ /** /**
* @brief DMA enable * @brief DMA enable
* *
* @param ch: DMA channel number * @param ch: DMA channel number
* *
* @return None * @return None
* *
*******************************************************************************/ *******************************************************************************/
void DMA_Channel_Enable(uint8_t ch) { void DMA_Channel_Enable(uint8_t ch) {
uint32_t tmpVal; uint32_t tmpVal;
/* Get channel register */ /* Get channel register */
@@ -350,14 +354,14 @@ void DMA_Channel_Enable(uint8_t ch) {
BL_WR_REG(DMAChs, DMA_CONFIG, tmpVal); BL_WR_REG(DMAChs, DMA_CONFIG, tmpVal);
} }
/****************************************************************************/ /** /**
* @brief DMA disable * @brief DMA disable
* *
* @param ch: DMA channel number * @param ch: DMA channel number
* *
* @return None * @return None
* *
*******************************************************************************/ *******************************************************************************/
void DMA_Channel_Disable(uint8_t ch) { void DMA_Channel_Disable(uint8_t ch) {
uint32_t tmpVal; uint32_t tmpVal;
/* Get channel register */ /* Get channel register */
@@ -371,15 +375,15 @@ void DMA_Channel_Disable(uint8_t ch) {
BL_WR_REG(DMAChs, DMA_CONFIG, tmpVal); BL_WR_REG(DMAChs, DMA_CONFIG, tmpVal);
} }
/****************************************************************************/ /** /**
* @brief DMA init LLI transfer * @brief DMA init LLI transfer
* *
* @param ch: DMA channel number * @param ch: DMA channel number
* @param lliCfg: LLI configuration * @param lliCfg: LLI configuration
* *
* @return None * @return None
* *
*******************************************************************************/ *******************************************************************************/
void DMA_LLI_Init(uint8_t ch, DMA_LLI_Cfg_Type *lliCfg) { void DMA_LLI_Init(uint8_t ch, DMA_LLI_Cfg_Type *lliCfg) {
uint32_t tmpVal; uint32_t tmpVal;
/* Get channel register */ /* Get channel register */
@@ -401,15 +405,15 @@ void DMA_LLI_Init(uint8_t ch, DMA_LLI_Cfg_Type *lliCfg) {
BL_WR_REG(DMAChs, DMA_CONFIG, tmpVal); BL_WR_REG(DMAChs, DMA_CONFIG, tmpVal);
} }
/****************************************************************************/ /** /**
* @brief DMA channel update LLI * @brief DMA channel update LLI
* *
* @param ch: DMA channel number * @param ch: DMA channel number
* @param LLI: LLI addr * @param LLI: LLI addr
* *
* @return None * @return None
* *
*******************************************************************************/ *******************************************************************************/
void DMA_LLI_Update(uint8_t ch, uint32_t LLI) { void DMA_LLI_Update(uint8_t ch, uint32_t LLI) {
/* Get channel register */ /* Get channel register */
uint32_t DMAChs = DMA_Get_Channel(ch); uint32_t DMAChs = DMA_Get_Channel(ch);
@@ -422,152 +426,16 @@ void DMA_LLI_Update(uint8_t ch, uint32_t LLI) {
BL702_MemCpy4((uint32_t *)DMAChs, (uint32_t *)LLI, 4); BL702_MemCpy4((uint32_t *)DMAChs, (uint32_t *)LLI, 4);
} }
/****************************************************************************/ /** /**
* @brief DMA LLI PingPong Structure Start * @brief Mask/Unmask the DMA interrupt
* *
* @param dmaPpStruct: dma pp struct pointer * @param ch: DMA channel number
* @param Ping_Transfer_len: ping len * @param intType: Specifies the interrupt type
* @param Pong_Transfer_len: pong len * @param intMask: Enable/Disable Specified interrupt type
* *
* @return Succrss or not * @return None
* *
*******************************************************************************/ *******************************************************************************/
BL_Err_Type DMA_LLI_PpStruct_Set_Transfer_Len(DMA_LLI_PP_Struct *dmaPpStruct, uint16_t Ping_Transfer_len, uint16_t Pong_Transfer_len) {
struct DMA_Control_Reg dmaCtrlRegVal_temp;
if (Ping_Transfer_len > 4096 || Pong_Transfer_len > 4096) {
return ERROR;
}
dmaCtrlRegVal_temp = PingPongListArra[dmaPpStruct->dmaChan][PING_INDEX].dmaCtrl;
dmaCtrlRegVal_temp.TransferSize = Ping_Transfer_len;
PingPongListArra[dmaPpStruct->dmaChan][PING_INDEX].dmaCtrl = dmaCtrlRegVal_temp;
dmaCtrlRegVal_temp = PingPongListArra[dmaPpStruct->dmaChan][PONG_INDEX].dmaCtrl;
dmaCtrlRegVal_temp.TransferSize = Pong_Transfer_len;
PingPongListArra[dmaPpStruct->dmaChan][PONG_INDEX].dmaCtrl = dmaCtrlRegVal_temp;
DMA_LLI_Init(dmaPpStruct->dmaChan, dmaPpStruct->DMA_LLI_Cfg);
DMA_LLI_Update(dmaPpStruct->dmaChan, (uint32_t)&PingPongListArra[dmaPpStruct->dmaChan][PING_INDEX]);
return SUCCESS;
}
/****************************************************************************/ /**
* @brief DMA LLI Start New Transmit for Ping-Pong Buf
*
* @param dmaPpBuf: DMA LLI Ping-Pong Buf
*
* @return None
*
*******************************************************************************/
void DMA_LLI_PpBuf_Start_New_Transmit(DMA_LLI_PP_Buf *dmaPpBuf) {
CPU_Interrupt_Disable(DMA_ALL_IRQn);
if (dmaPpBuf->lliListHeader[dmaPpBuf->idleIndex] != NULL) {
DMA_LLI_Update(dmaPpBuf->dmaChan, (uint32_t)dmaPpBuf->lliListHeader[dmaPpBuf->idleIndex]);
DMA_Channel_Enable(dmaPpBuf->dmaChan);
dmaPpBuf->idleIndex = (dmaPpBuf->idleIndex == 0) ? 1 : 0;
}
CPU_Interrupt_Enable(DMA_ALL_IRQn);
}
/****************************************************************************/ /**
* @brief DMA LLI Remove Completed Ping-Pong Buf List
*
* @param dmaPpBuf: DMA LLI Ping-Pong Buf
*
* @return Next Ping-Pong Buf List Header
*
*******************************************************************************/
DMA_LLI_Ctrl_Type *DMA_LLI_PpBuf_Remove_Completed_List(DMA_LLI_PP_Buf *dmaPpBuf) {
CPU_Interrupt_Disable(DMA_ALL_IRQn);
dmaPpBuf->lliListHeader[!dmaPpBuf->idleIndex] = NULL;
CPU_Interrupt_Enable(DMA_ALL_IRQn);
return dmaPpBuf->lliListHeader[!dmaPpBuf->idleIndex];
}
/****************************************************************************/ /**
* @brief DMA LLI Append Buf to List
*
* @param dmaPpBuf: DMA LLI Ping-Pong Buf
* @param dmaLliList: New LLI Buf to Append
*
* @return None
*
*******************************************************************************/
void DMA_LLI_PpBuf_Append(DMA_LLI_PP_Buf *dmaPpBuf, DMA_LLI_Ctrl_Type *dmaLliList) {
DMA_LLI_Ctrl_Type *pLliList = NULL;
CPU_Interrupt_Disable(DMA_ALL_IRQn);
pLliList = dmaPpBuf->lliListHeader[dmaPpBuf->idleIndex];
if (pLliList == NULL) {
dmaLliList->nextLLI = 0;
dmaLliList->dmaCtrl.I = 1;
dmaPpBuf->lliListHeader[dmaPpBuf->idleIndex] = dmaLliList;
} else {
/*Append to last */
while (pLliList->nextLLI != 0) {
pLliList = (DMA_LLI_Ctrl_Type *)pLliList->nextLLI;
}
pLliList->nextLLI = (uint32_t)dmaLliList;
pLliList->dmaCtrl.I = 0;
dmaLliList->nextLLI = 0;
dmaLliList->dmaCtrl.I = 1;
}
if (DMA_Channel_Is_Busy(dmaPpBuf->dmaChan) == RESET) {
/* DMA stopped: maybe stop just a few minutes ago(not enter INT due to CPU_Interrupt_Disable)
or has already stopped before this function is called */
if (dmaPpBuf->lliListHeader[!dmaPpBuf->idleIndex] == NULL) {
/* DMA has already stopped before this function is called */
DMA_LLI_PpBuf_Start_New_Transmit(dmaPpBuf);
}
}
CPU_Interrupt_Enable(DMA_ALL_IRQn);
}
/****************************************************************************/ /**
* @brief DMA LLi Destroy Ping-Pong Buf
*
* @param dmaPpBuf: DMA LLI Ping-Pong Buf
*
* @return None
*
*******************************************************************************/
void DMA_LLI_PpBuf_Destroy(DMA_LLI_PP_Buf *dmaPpBuf) {
/* DMA LLI Disable */
DMA_Channel_Disable(dmaPpBuf->dmaChan);
if (dmaPpBuf->lliListHeader[0] != NULL && dmaPpBuf->onTransCompleted != NULL) {
dmaPpBuf->onTransCompleted(dmaPpBuf->lliListHeader[0]);
}
dmaPpBuf->lliListHeader[0] = NULL;
if (dmaPpBuf->lliListHeader[1] != NULL && dmaPpBuf->onTransCompleted != NULL) {
dmaPpBuf->onTransCompleted(dmaPpBuf->lliListHeader[1]);
}
dmaPpBuf->lliListHeader[1] = NULL;
dmaPpBuf->idleIndex = 0;
}
/****************************************************************************/ /**
* @brief Mask/Unmask the DMA interrupt
*
* @param ch: DMA channel number
* @param intType: Specifies the interrupt type
* @param intMask: Enable/Disable Specified interrupt type
*
* @return None
*
*******************************************************************************/
void DMA_IntMask(uint8_t ch, DMA_INT_Type intType, BL_Mask_Type intMask) { void DMA_IntMask(uint8_t ch, DMA_INT_Type intType, BL_Mask_Type intMask) {
uint32_t tmpVal; uint32_t tmpVal;
/* Get channel register */ /* Get channel register */
@@ -636,16 +504,16 @@ void DMA_IntMask(uint8_t ch, DMA_INT_Type intType, BL_Mask_Type intMask) {
} }
} }
/****************************************************************************/ /** /**
* @brief Install DMA interrupt callback function * @brief Install DMA interrupt callback function
* *
* @param dmaChan: DMA Channel type * @param dmaChan: DMA Channel type
* @param intType: DMA interrupt type * @param intType: DMA interrupt type
* @param cbFun: Pointer to interrupt callback function. The type should be void (*fn)(void) * @param cbFun: Pointer to interrupt callback function. The type should be void (*fn)(void)
* *
* @return None * @return None
* *
*******************************************************************************/ *******************************************************************************/
void DMA_Int_Callback_Install(DMA_Chan_Type dmaChan, DMA_INT_Type intType, intCallback_Type *cbFun) { void DMA_Int_Callback_Install(DMA_Chan_Type dmaChan, DMA_INT_Type intType, intCallback_Type *cbFun) {
/* Check the parameters */ /* Check the parameters */
CHECK_PARAM(IS_DMA_CHAN_TYPE(dmaChan)); CHECK_PARAM(IS_DMA_CHAN_TYPE(dmaChan));
@@ -654,69 +522,6 @@ void DMA_Int_Callback_Install(DMA_Chan_Type dmaChan, DMA_INT_Type intType, intCa
dmaIntCbfArra[dmaChan][intType] = cbFun; dmaIntCbfArra[dmaChan][intType] = cbFun;
} }
/****************************************************************************/ /**
* @brief DMA LLI PingPong Structure Initial
*
* @param dmaPpStruct: DMA LLI PingPong Config Parameter
*
* @return start success or not
*
*******************************************************************************/
BL_Err_Type DMA_LLI_PpStruct_Init(DMA_LLI_PP_Struct *dmaPpStruct) {
// setup lliList
dmaPpStruct->dmaCtrlRegVal.I = 1;
dmaPpStruct->trans_index = 0;
if (dmaPpStruct->DMA_LLI_Cfg->dir == DMA_TRNS_M2P) {
PingPongListArra[dmaPpStruct->dmaChan][PING_INDEX].srcDmaAddr = dmaPpStruct->chache_buf_addr[0];
PingPongListArra[dmaPpStruct->dmaChan][PING_INDEX].destDmaAddr = dmaPpStruct->operatePeriphAddr;
PingPongListArra[dmaPpStruct->dmaChan][PONG_INDEX].srcDmaAddr = dmaPpStruct->chache_buf_addr[1];
PingPongListArra[dmaPpStruct->dmaChan][PONG_INDEX].destDmaAddr = dmaPpStruct->operatePeriphAddr;
} else if (dmaPpStruct->DMA_LLI_Cfg->dir == DMA_TRNS_P2M) {
PingPongListArra[dmaPpStruct->dmaChan][PING_INDEX].srcDmaAddr = dmaPpStruct->operatePeriphAddr;
PingPongListArra[dmaPpStruct->dmaChan][PING_INDEX].destDmaAddr = dmaPpStruct->chache_buf_addr[0];
PingPongListArra[dmaPpStruct->dmaChan][PONG_INDEX].srcDmaAddr = dmaPpStruct->operatePeriphAddr;
PingPongListArra[dmaPpStruct->dmaChan][PONG_INDEX].destDmaAddr = dmaPpStruct->chache_buf_addr[1];
} else {
return ERROR;
/*V1.0 version DMA LLI Ping-Pong structure not support P2P & M2M MODE*/
}
PingPongListArra[dmaPpStruct->dmaChan][PING_INDEX].nextLLI = (uint32_t)&PingPongListArra[dmaPpStruct->dmaChan][PONG_INDEX];
PingPongListArra[dmaPpStruct->dmaChan][PING_INDEX].dmaCtrl = dmaPpStruct->dmaCtrlRegVal;
PingPongListArra[dmaPpStruct->dmaChan][PONG_INDEX].nextLLI = (uint32_t)&PingPongListArra[dmaPpStruct->dmaChan][PING_INDEX];
PingPongListArra[dmaPpStruct->dmaChan][PONG_INDEX].dmaCtrl = dmaPpStruct->dmaCtrlRegVal;
DMA_LLI_Init(dmaPpStruct->dmaChan, dmaPpStruct->DMA_LLI_Cfg);
DMA_LLI_Update(dmaPpStruct->dmaChan, (uint32_t)&PingPongListArra[dmaPpStruct->dmaChan][PING_INDEX]);
return SUCCESS;
}
/****************************************************************************/ /**
* @brief DMA LLI PingPong Structure Start
*
* @param dmaPpStruct: None
*
* @return None
*
*******************************************************************************/
void DMA_LLI_PpStruct_Start(DMA_LLI_PP_Struct *dmaPpStruct) { DMA_Channel_Enable(dmaPpStruct->dmaChan); }
/****************************************************************************/ /**
* @brief DMA LLI PingPong Structure Stop
*
* @param dmaPpStruct: None
*
* @return None
*
*******************************************************************************/
void DMA_LLI_PpStruct_Stop(DMA_LLI_PP_Struct *dmaPpStruct) { DMA_Channel_Disable(dmaPpStruct->dmaChan); }
/*@} end of group DMA_Public_Functions */ /*@} end of group DMA_Public_Functions */
/*@} end of group DMA */ /*@} end of group DMA */

View File

@@ -205,11 +205,58 @@ void I2C_Enable(I2C_ID_Type i2cNo) {
/* Check the parameters */ /* Check the parameters */
CHECK_PARAM(IS_I2C_ID_TYPE(i2cNo)); CHECK_PARAM(IS_I2C_ID_TYPE(i2cNo));
// Set the M_EN bit
tmpVal = BL_RD_REG(I2Cx, I2C_CONFIG); tmpVal = BL_RD_REG(I2Cx, I2C_CONFIG);
tmpVal = BL_SET_REG_BIT(tmpVal, I2C_CR_I2C_M_EN); tmpVal = BL_SET_REG_BIT(tmpVal, I2C_CR_I2C_M_EN);
BL_WR_REG(I2Cx, I2C_CONFIG, tmpVal); BL_WR_REG(I2Cx, I2C_CONFIG, tmpVal);
} }
uint8_t I2C_GetTXFIFOAvailable() {
volatile uint32_t tmpVal;
uint32_t I2Cx = I2C_BASE;
tmpVal = BL_RD_REG(I2Cx, I2C_FIFO_CONFIG_1);
return tmpVal & 0b11; // Lowest two bits
}
void I2C_DMATxEnable() {
uint32_t tmpVal;
uint32_t I2Cx = I2C_BASE;
tmpVal = BL_RD_REG(I2Cx, I2C_FIFO_CONFIG_0);
tmpVal = BL_SET_REG_BIT(tmpVal, I2C_DMA_TX_EN);
tmpVal = BL_SET_REG_BIT(tmpVal, I2C_TX_FIFO_CLR);
tmpVal = BL_SET_REG_BIT(tmpVal, I2C_RX_FIFO_CLR);
// tmpVal = BL_SET_REG_BIT(tmpVal, I2C_DMA_RX_EN);
BL_WR_REG(I2Cx, I2C_FIFO_CONFIG_0, tmpVal);
// Ensure fifo setpoint is as we expect
tmpVal = BL_RD_REG(I2Cx, I2C_FIFO_CONFIG_1);
tmpVal &= I2C_TX_FIFO_CNT_UMSK;
tmpVal |= 1;
BL_WR_REG(I2Cx, I2C_FIFO_CONFIG_1, tmpVal);
}
void I2C_DMATxDisable() {
uint32_t tmpVal;
uint32_t I2Cx = I2C_BASE;
tmpVal = BL_RD_REG(I2Cx, I2C_FIFO_CONFIG_0);
tmpVal = BL_CLR_REG_BIT(tmpVal, I2C_DMA_TX_EN);
// tmpVal = BL_CLR_REG_BIT(tmpVal, I2C_DMA_RX_EN);
BL_WR_REG(I2Cx, I2C_FIFO_CONFIG_0, tmpVal);
tmpVal = BL_RD_REG(I2Cx, I2C_FIFO_CONFIG_1);
tmpVal &= I2C_TX_FIFO_CNT_UMSK;
tmpVal |= 1;
BL_WR_REG(I2Cx, I2C_FIFO_CONFIG_1, tmpVal);
}
/** /**
* @brief I2C disable * @brief I2C disable
* *
@@ -297,15 +344,15 @@ void I2C_Init(I2C_ID_Type i2cNo, I2C_Direction_Type direct, I2C_Transfer_Cfg *cf
tmpVal = BL_CLR_REG_BIT(tmpVal, I2C_CR_I2C_SUB_ADDR_EN); tmpVal = BL_CLR_REG_BIT(tmpVal, I2C_CR_I2C_SUB_ADDR_EN);
} }
// Packet length <=256 bytes per transaction
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, I2C_CR_I2C_PKT_LEN, cfg->dataSize - 1); tmpVal = BL_SET_REG_BITS_VAL(tmpVal, I2C_CR_I2C_PKT_LEN, cfg->dataSize - 1);
BL_WR_REG(I2Cx, I2C_CONFIG, tmpVal); BL_WR_REG(I2Cx, I2C_CONFIG, tmpVal);
/* Set sub address */ /* Set sub address */
BL_WR_REG(I2Cx, I2C_SUB_ADDR, cfg->subAddr); BL_WR_REG(I2Cx, I2C_SUB_ADDR, cfg->subAddr);
#ifndef BFLB_USE_HAL_DRIVER
Interrupt_Handler_Register(I2C_IRQn, I2C_IRQHandler); Interrupt_Handler_Register(I2C_IRQn, I2C_IRQHandler);
#endif
} }
/** /**

View File

@@ -24,9 +24,9 @@ OLED::DisplayState OLED::displayState;
int16_t OLED::cursor_x, OLED::cursor_y; int16_t OLED::cursor_x, OLED::cursor_y;
bool OLED::initDone = false; bool OLED::initDone = false;
uint8_t OLED::displayOffset; uint8_t OLED::displayOffset;
uint8_t OLED::screenBuffer[16 + (OLED_WIDTH * (OLED_HEIGHT / 8)) + 10]; // The data buffer alignas(uint32_t) uint8_t OLED::screenBuffer[16 + (OLED_WIDTH * (OLED_HEIGHT / 8)) + 10]; // The data buffer
uint8_t OLED::secondFrameBuffer[16 + (OLED_WIDTH * (OLED_HEIGHT / 8)) + 10]; alignas(uint32_t) uint8_t OLED::secondFrameBuffer[16 + (OLED_WIDTH * (OLED_HEIGHT / 8)) + 10];
uint32_t OLED::displayChecksum; uint32_t OLED::displayChecksum;
/* /*
* Setup params for the OLED screen * Setup params for the OLED screen
* http://www.displayfuture.com/Display/datasheet/controller/SSD1307.pdf * http://www.displayfuture.com/Display/datasheet/controller/SSD1307.pdf

View File

@@ -186,6 +186,7 @@ void guiRenderLoop(void) {
} }
// Render done, draw it out // Render done, draw it out
OLED::refresh(); OLED::refresh();
osDelay(10);
} }
OperatingMode handle_post_init_state() { OperatingMode handle_post_init_state() {