mirror of
https://github.com/Ralim/IronOS.git
synced 2025-02-26 07:53:55 +00:00
Compare commits
11 Commits
update
...
0ed2d84fca
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ed2d84fca | ||
|
|
622d8aac07 | ||
|
|
4087fc60ed | ||
|
|
c4df679b21 | ||
|
|
166339e74d | ||
|
|
786a0a41e5 | ||
|
|
5c7cfe2e19 | ||
|
|
48b28123a6 | ||
|
|
c2ec65cafb | ||
|
|
53982efa14 | ||
|
|
be1536b82f |
@@ -24,7 +24,7 @@ In general you probably want `master`.
|
||||
Once you click on a run, scroll down to the "Artifacts" section and then click on your device model name to download a zip file.
|
||||
Then this works the same as a production release (use the correct file).
|
||||
|
||||
# Pinecil V2
|
||||
## Pinecil V2
|
||||
|
||||
- The MCU in Pinecil V2 is Bouffalo BL706 and does _not_ use usb-dfu for flashing as the previous Pinecil V1 MCU did.
|
||||
- See the Pinecil Wiki page [here](https://wiki.pine64.org/wiki/Pinecil#Firmware_&_Updates) for instructions.
|
||||
@@ -34,3 +34,16 @@ Then this works the same as a production release (use the correct file).
|
||||
- One advantage of Pinecil is that you cannot permanently damage it doing a firmware update (because BIN is in ROM); an update could render Pinecil temporarily inoperable if you flash an invalid firmware. But no worries, simply re-flashing with a working firmware copy will fix everything.
|
||||
- USB-C cable is required to do an update. Generally, all USB controllers work, but some hubs have issues, so it is preferred to avoid USB hubs for updates.
|
||||
- Background on the [BL706 chipset](https://lupyuen.github.io/articles/bl706)
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
If you are running into issues such as timeouts during the programming or bootloader errors, the BL702 has a not-amazing USB PHY built in. This can cause problems on cheap cables (especially "thin" ones that tend not to have shielding). One of the authors (Ralim) has found this especially common on the cables supplied with Apple chargers when used with newer Ryzen processor ports.
|
||||
|
||||
It is _strongly_ reccomended to use a good quality cable, ideally _short_.
|
||||
Also try other USB ports, as on some devices they can use different hub's or lengths of signalling, and this can fix the issue.
|
||||
|
||||
By the PinecilV2's design, by default some of the internal buses are exposed on the USB3 pins, to enable hacking/debugging/mods. This is suspected it _may_ play poorly on some chipsets. Try using a USB2.0 cable. Others have had luck with chaining USB-C->USB-A->USB-C. This may be due to this, as a lot of these adaptors are USB2 or only USB3 5gbps (half USB3 pins).
|
||||
|
||||
Another workaround is to put a USB hub somewhere in the chain, as these will re-form the signal and can work around the issue.
|
||||
|
||||
_Finally_, some users have reported issues under Windows that were fixed by changing OS (Typically to a Linux live cd).
|
||||
|
||||
@@ -278,7 +278,7 @@ uint8_t getDeviceValidationStatus() {
|
||||
}
|
||||
|
||||
void showBootLogo(void) {
|
||||
uint8_t scratch[1024];
|
||||
alignas(uint32_t) uint8_t scratch[1024];
|
||||
flash_read(FLASH_LOGOADDR - 0x23000000, scratch, 1024);
|
||||
|
||||
BootLogo::handleShowingLogo(scratch);
|
||||
|
||||
@@ -7,17 +7,125 @@
|
||||
#include "BSP.h"
|
||||
#include "IRQ.h"
|
||||
#include "Setup.h"
|
||||
#include "bl_mcu_sdk/drivers/bl702_driver/std_drv/inc/bl702_dma.h"
|
||||
extern "C" {
|
||||
#include "bflb_platform.h"
|
||||
#include "bl702_dma.h"
|
||||
#include "bl702_glb.h"
|
||||
#include "bl702_i2c.h"
|
||||
}
|
||||
#include <I2C_Wrapper.hpp>
|
||||
|
||||
// Semaphore for locking users of I2C
|
||||
SemaphoreHandle_t FRToSI2C::I2CSemaphore = nullptr;
|
||||
StaticSemaphore_t FRToSI2C::xSemaphoreBuffer;
|
||||
#define I2C_TIME_OUT (uint16_t)(12000)
|
||||
void FRToSI2C::CpltCallback() {} // Not used
|
||||
#define I2C_TIME_OUT (uint16_t)(12000)
|
||||
#define I2C_TX_FIFO_ADDR (0x4000A300 + 0x88)
|
||||
#define I2C_RX_FIFO_ADDR (0x4000A300 + 0x8C)
|
||||
|
||||
// Used by the irq handler
|
||||
|
||||
volatile uint8_t *IRQDataPointer;
|
||||
volatile uint8_t IRQDataSizeLeft;
|
||||
volatile bool IRQFailureMarker;
|
||||
volatile TaskHandle_t IRQTaskWaitingHandle = NULL;
|
||||
/****** 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 (IRQDataSizeLeft > 0 && I2C_GetTXFIFOAvailable() > 0) {
|
||||
// Can put in at least 1 byte
|
||||
|
||||
// Build a 32-bit word from bytes
|
||||
uint32_t value = 0;
|
||||
int packing = IRQDataSizeLeft >= 4 ? 0 : 4 - IRQDataSizeLeft;
|
||||
for (int i = 0; i < 4 && IRQDataSizeLeft > 0; i++) {
|
||||
value >>= 8;
|
||||
value |= (*IRQDataPointer) << 24; // Shift to the left, adding new data to the higher byte
|
||||
IRQDataPointer++; // Shift to next byte
|
||||
IRQDataSizeLeft--;
|
||||
}
|
||||
// Handle shunting remaining bytes if not a full 4 to send
|
||||
for (int i = 0; i < packing; i++) {
|
||||
value >>= 8;
|
||||
}
|
||||
// Push the new value to the fifo
|
||||
*((volatile uint32_t *)I2C_TX_FIFO_ADDR) = value;
|
||||
}
|
||||
if (IRQDataSizeLeft == 0) {
|
||||
// Disable IRQ, were done
|
||||
I2C_IntMask(I2C0_ID, I2C_TX_FIFO_READY_INT, MASK);
|
||||
}
|
||||
}
|
||||
|
||||
void i2c_rx_pop_fifo() {
|
||||
// Pop one word from the fifo and store it
|
||||
uint32_t value = *((uint32_t *)I2C_RX_FIFO_ADDR);
|
||||
|
||||
for (int i = 0; i < 4 && IRQDataSizeLeft > 0; i++) {
|
||||
*IRQDataPointer = value & 0xFF;
|
||||
IRQDataPointer++;
|
||||
IRQDataSizeLeft--;
|
||||
value >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
void i2c_irq_rx_fifo_ready() {
|
||||
// Draining the Rx FiFo
|
||||
while (I2C_GetRXFIFOAvailable() > 0) {
|
||||
i2c_rx_pop_fifo();
|
||||
}
|
||||
|
||||
if (IRQDataSizeLeft == 0) {
|
||||
// Disable IRQ, were done
|
||||
I2C_IntMask(I2C0_ID, I2C_RX_FIFO_READY_INT, MASK);
|
||||
}
|
||||
}
|
||||
|
||||
void i2c_irq_done_read() {
|
||||
IRQFailureMarker = false;
|
||||
// If there was a non multiple of 4 bytes to be read, they are pushed to the fifo now (end of transfer interrupt)
|
||||
// So we catch them here
|
||||
while (I2C_GetRXFIFOAvailable() > 0) {
|
||||
i2c_rx_pop_fifo();
|
||||
}
|
||||
|
||||
// Mask IRQ's back off
|
||||
FRToSI2C::CpltCallback(); // Causes the lock to be released
|
||||
}
|
||||
void i2c_irq_done() {
|
||||
IRQFailureMarker = false;
|
||||
// Mask IRQ's back off
|
||||
FRToSI2C::CpltCallback(); // Causes the lock to be released
|
||||
}
|
||||
void i2c_irq_nack() {
|
||||
IRQFailureMarker = true;
|
||||
// Mask IRQ's back off
|
||||
FRToSI2C::CpltCallback(); // Causes the lock to be released
|
||||
}
|
||||
|
||||
/****** END IRQ Handlers ******/
|
||||
void FRToSI2C::CpltCallback() {
|
||||
// This is only triggered from IRQ context
|
||||
I2C_IntMask(I2C0_ID, I2C_TX_FIFO_READY_INT, MASK);
|
||||
I2C_IntMask(I2C0_ID, I2C_RX_FIFO_READY_INT, MASK);
|
||||
I2C_IntMask(I2C0_ID, I2C_TRANS_END_INT, MASK);
|
||||
I2C_IntMask(I2C0_ID, I2C_NACK_RECV_INT, MASK);
|
||||
|
||||
CPU_Interrupt_Disable(I2C_IRQn); // Disable IRQ's
|
||||
|
||||
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);
|
||||
xTaskNotifyFromISR(IRQTaskWaitingHandle, IRQFailureMarker ? 2 : 1, eSetValueWithOverwrite, &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); }
|
||||
|
||||
@@ -40,22 +148,37 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t read_address, uint8_t *p_b
|
||||
i2cCfg.data = p_buffer;
|
||||
i2cCfg.subAddrSize = 1; // one byte address
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
/* --------------- */
|
||||
err = I2C_MasterReceiveBlocking(I2C0_ID, &i2cCfg);
|
||||
taskEXIT_CRITICAL();
|
||||
bool res = err == SUCCESS;
|
||||
if (!res) {
|
||||
I2C_Unstick();
|
||||
}
|
||||
unlock();
|
||||
return res;
|
||||
// Store handles for IRQ
|
||||
IRQDataPointer = p_buffer;
|
||||
IRQDataSizeLeft = number_of_byte;
|
||||
IRQTaskWaitingHandle = xTaskGetCurrentTaskHandle();
|
||||
IRQFailureMarker = false;
|
||||
|
||||
I2C_Disable(I2C0_ID);
|
||||
// Setup and run
|
||||
I2C_Init(I2C0_ID, I2C_READ, &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_RX_FIFO_READY_INT, UNMASK);
|
||||
I2C_Int_Callback_Install(I2C0_ID, I2C_TRANS_END_INT, i2c_irq_done_read);
|
||||
I2C_Int_Callback_Install(I2C0_ID, I2C_NACK_RECV_INT, i2c_irq_nack);
|
||||
I2C_Int_Callback_Install(I2C0_ID, I2C_RX_FIFO_READY_INT, i2c_irq_rx_fifo_ready);
|
||||
CPU_Interrupt_Enable(I2C_IRQn);
|
||||
|
||||
// Start
|
||||
I2C_Enable(I2C0_ID);
|
||||
|
||||
// Wait for transfer in background
|
||||
uint32_t result = 0;
|
||||
xTaskNotifyWait(0xFFFFFFFF, 0xFFFFFFFF, &result, TICKS_100MS);
|
||||
return result == 1;
|
||||
}
|
||||
|
||||
bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *p_buffer, uint16_t number_of_byte) {
|
||||
if (!lock()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
I2C_Transfer_Cfg i2cCfg = {0, DISABLE, 0, 0, 0, 0};
|
||||
BL_Err_Type err = ERROR;
|
||||
i2cCfg.slaveAddr = DevAddress >> 1;
|
||||
@@ -65,16 +188,31 @@ bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *p_bu
|
||||
i2cCfg.data = p_buffer;
|
||||
i2cCfg.subAddrSize = 1; // one byte address
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
/* --------------- */
|
||||
err = I2C_MasterSendBlocking(I2C0_ID, &i2cCfg);
|
||||
taskEXIT_CRITICAL();
|
||||
bool res = err == SUCCESS;
|
||||
if (!res) {
|
||||
I2C_Unstick();
|
||||
}
|
||||
unlock();
|
||||
return res;
|
||||
// Store handles for IRQ
|
||||
IRQDataPointer = p_buffer;
|
||||
IRQDataSizeLeft = number_of_byte;
|
||||
IRQTaskWaitingHandle = xTaskGetCurrentTaskHandle();
|
||||
IRQFailureMarker = false;
|
||||
|
||||
// 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);
|
||||
CPU_Interrupt_Enable(I2C_IRQn);
|
||||
|
||||
i2c_irq_tx_fifo_low();
|
||||
|
||||
// Start
|
||||
I2C_Enable(I2C0_ID);
|
||||
|
||||
// Wait for transfer in background
|
||||
uint32_t result = 0;
|
||||
xTaskNotifyWait(0xFFFFFFFF, 0xFFFFFFFF, &result, TICKS_100MS);
|
||||
return result == 1;
|
||||
}
|
||||
|
||||
bool FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) { return Mem_Write(DevAddress, pData[0], pData + 1, Size - 1); }
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "FreeRTOSConfig.h"
|
||||
#include "IRQ.h"
|
||||
#include "Pins.h"
|
||||
#include "bl702_dma.h"
|
||||
#include "bl702_sec_eng.h"
|
||||
#include "history.hpp"
|
||||
#include <string.h>
|
||||
@@ -66,7 +67,9 @@ void hardware_init() {
|
||||
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
|
||||
// 200kHz and above works
|
||||
|
||||
I2C_ClockSet(I2C0_ID, 300000); // Sets clock to around 25 kHz less than set here
|
||||
|
||||
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_0, 0);
|
||||
}
|
||||
void setup_pwm(void) {
|
||||
|
||||
@@ -92,8 +92,8 @@ int dma_open(struct device *dev, uint16_t oflag) {
|
||||
chCfg.dstPeriph = dma_device->dst_req;
|
||||
chCfg.srcAddrInc = dma_device->src_addr_inc;
|
||||
chCfg.destAddrInc = dma_device->dst_addr_inc;
|
||||
chCfg.srcBurstSzie = dma_device->src_burst_size;
|
||||
chCfg.dstBurstSzie = dma_device->dst_burst_size;
|
||||
chCfg.srcBurstSize = dma_device->src_burst_size;
|
||||
chCfg.dstBurstSize = dma_device->dst_burst_size;
|
||||
chCfg.srcTransfWidth = dma_device->src_width;
|
||||
chCfg.dstTransfWidth = dma_device->dst_width;
|
||||
DMA_Channel_Init(&chCfg);
|
||||
|
||||
@@ -39,6 +39,10 @@
|
||||
#include "dma_reg.h"
|
||||
#include "bl702_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup BL702_Peripheral_Driver
|
||||
* @{
|
||||
*/
|
||||
@@ -168,9 +172,9 @@ typedef struct
|
||||
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 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 */
|
||||
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 */
|
||||
BL_Fun_Type dstAddMode; /*!< */
|
||||
BL_Fun_Type dstMinMode; /*!< */
|
||||
@@ -181,16 +185,6 @@ typedef struct
|
||||
DMA_Periph_Req_Type dstPeriph; /*!< Destination peripheral select */
|
||||
} 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
|
||||
@@ -202,31 +196,6 @@ typedef struct
|
||||
DMA_Periph_Req_Type dstPeriph; /*!< Destination peripheral select */
|
||||
} 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 */
|
||||
|
||||
@@ -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_Update(uint8_t ch, uint32_t LLI);
|
||||
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_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 */
|
||||
|
||||
@@ -363,4 +323,8 @@ BL_Err_Type DMA_LLI_PpStruct_Set_Transfer_Len(DMA_LLI_PP_Struct *dmaPpStruct,
|
||||
|
||||
/*@} end of group BL702_Peripheral_Driver */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __BL702_DMA_H__ */
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file bl702_i2c.h
|
||||
* @version V1.0
|
||||
* @date
|
||||
* @brief This file is the standard driver header file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 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
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
******************************************************************************
|
||||
* @file bl702_i2c.h
|
||||
* @version V1.0
|
||||
* @date
|
||||
* @brief This file is the standard driver header file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 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
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef __BL702_I2C_H__
|
||||
#define __BL702_I2C_H__
|
||||
|
||||
#include "i2c_reg.h"
|
||||
#include "bl702_common.h"
|
||||
#include "i2c_reg.h"
|
||||
|
||||
/** @addtogroup BL702_Peripheral_Driver
|
||||
* @{
|
||||
@@ -55,75 +55,71 @@
|
||||
* @brief I2C No. type definition
|
||||
*/
|
||||
typedef enum {
|
||||
I2C0_ID = 0, /*!< I2C0 define */
|
||||
I2C_ID_MAX, /*!< I2C max define */
|
||||
I2C0_ID = 0, /*!< I2C0 define */
|
||||
I2C_ID_MAX, /*!< I2C max define */
|
||||
} I2C_ID_Type;
|
||||
|
||||
/**
|
||||
* @brief I2C read/write type definition
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_WRITE = 0, /*!< I2C write direction */
|
||||
I2C_READ, /*!< I2C read direction */
|
||||
I2C_WRITE = 0, /*!< I2C write direction */
|
||||
I2C_READ, /*!< I2C read direction */
|
||||
} I2C_Direction_Type;
|
||||
|
||||
/**
|
||||
* @brief I2C interrupt type definition
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_TRANS_END_INT, /*!< I2C transfer end interrupt */
|
||||
I2C_TX_FIFO_READY_INT, /*!< I2C TX fifo ready interrupt */
|
||||
I2C_RX_FIFO_READY_INT, /*!< I2C RX fifo ready interrupt */
|
||||
I2C_NACK_RECV_INT, /*!< I2C nack received interrupt */
|
||||
I2C_ARB_LOST_INT, /*!< I2C arbitration lost interrupt */
|
||||
I2C_FIFO_ERR_INT, /*!< I2C TX/RX FIFO error interrupt */
|
||||
I2C_INT_ALL, /*!< I2C interrupt all type */
|
||||
I2C_TRANS_END_INT, /*!< I2C transfer end interrupt */
|
||||
I2C_TX_FIFO_READY_INT, /*!< I2C TX fifo ready interrupt */
|
||||
I2C_RX_FIFO_READY_INT, /*!< I2C RX fifo ready interrupt */
|
||||
I2C_NACK_RECV_INT, /*!< I2C nack received interrupt */
|
||||
I2C_ARB_LOST_INT, /*!< I2C arbitration lost interrupt */
|
||||
I2C_FIFO_ERR_INT, /*!< I2C TX/RX FIFO error interrupt */
|
||||
I2C_INT_ALL, /*!< I2C interrupt all type */
|
||||
} I2C_INT_Type;
|
||||
|
||||
/**
|
||||
* @brief I2S start condition phase structure type definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t len0; /*!< Length of START condition phase 0 */
|
||||
uint8_t len1; /*!< Length of START condition phase 1 */
|
||||
uint8_t len2; /*!< Length of START condition phase 2 */
|
||||
uint8_t len3; /*!< Length of START condition phase 3 */
|
||||
typedef struct {
|
||||
uint8_t len0; /*!< Length of START condition phase 0 */
|
||||
uint8_t len1; /*!< Length of START condition phase 1 */
|
||||
uint8_t len2; /*!< Length of START condition phase 2 */
|
||||
uint8_t len3; /*!< Length of START condition phase 3 */
|
||||
} I2C_Start_Condition_Phase_Type;
|
||||
|
||||
/**
|
||||
* @brief I2S stop condition phase structure type definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t len0; /*!< Length of STOP condition phase 0 */
|
||||
uint8_t len1; /*!< Length of STOP condition phase 1 */
|
||||
uint8_t len2; /*!< Length of STOP condition phase 2 */
|
||||
uint8_t len3; /*!< Length of STOP condition phase 3 */
|
||||
typedef struct {
|
||||
uint8_t len0; /*!< Length of STOP condition phase 0 */
|
||||
uint8_t len1; /*!< Length of STOP condition phase 1 */
|
||||
uint8_t len2; /*!< Length of STOP condition phase 2 */
|
||||
uint8_t len3; /*!< Length of STOP condition phase 3 */
|
||||
} I2C_Stop_Condition_Phase_Type;
|
||||
|
||||
/**
|
||||
* @brief I2S data phase structure type definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t len0; /*!< Length of DATA phase 0 */
|
||||
uint8_t len1; /*!< Length of DATA phase 1 */
|
||||
uint8_t len2; /*!< Length of DATA phase 2 */
|
||||
uint8_t len3; /*!< Length of DATA phase 3 */
|
||||
typedef struct {
|
||||
uint8_t len0; /*!< Length of DATA phase 0 */
|
||||
uint8_t len1; /*!< Length of DATA phase 1 */
|
||||
uint8_t len2; /*!< Length of DATA phase 2 */
|
||||
uint8_t len3; /*!< Length of DATA phase 3 */
|
||||
} I2C_Data_Phase_Type;
|
||||
|
||||
/**
|
||||
* @brief I2S transfer structure type definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t slaveAddr; /*!< I2C slave address */
|
||||
BL_Fun_Type stopEveryByte; /*!< I2C all data byte with stop bit */
|
||||
uint8_t subAddrSize; /*!< Specifies the size of I2C sub address section */
|
||||
uint32_t subAddr; /*!< I2C sub address */
|
||||
uint16_t dataSize; /*!< Specifies the size of I2C data section */
|
||||
uint8_t *data; /*!< Specifies the pointer of I2C R/W data */
|
||||
typedef struct {
|
||||
uint8_t slaveAddr; /*!< I2C slave address */
|
||||
BL_Fun_Type stopEveryByte; /*!< I2C all data byte with stop bit */
|
||||
uint8_t subAddrSize; /*!< Specifies the size of I2C sub address section */
|
||||
uint32_t subAddr; /*!< I2C sub address */
|
||||
uint16_t dataSize; /*!< Specifies the size of I2C data section */
|
||||
uint8_t *data; /*!< Specifies the pointer of I2C R/W data */
|
||||
} I2C_Transfer_Cfg;
|
||||
|
||||
/*@} end of group I2C_Public_Types */
|
||||
@@ -135,25 +131,19 @@ typedef struct
|
||||
/** @defgroup I2C_ID_TYPE
|
||||
* @{
|
||||
*/
|
||||
#define IS_I2C_ID_TYPE(type) (((type) == I2C0_ID) || \
|
||||
((type) == I2C_ID_MAX))
|
||||
#define IS_I2C_ID_TYPE(type) (((type) == I2C0_ID) || ((type) == I2C_ID_MAX))
|
||||
|
||||
/** @defgroup I2C_DIRECTION_TYPE
|
||||
* @{
|
||||
*/
|
||||
#define IS_I2C_DIRECTION_TYPE(type) (((type) == I2C_WRITE) || \
|
||||
((type) == I2C_READ))
|
||||
#define IS_I2C_DIRECTION_TYPE(type) (((type) == I2C_WRITE) || ((type) == I2C_READ))
|
||||
|
||||
/** @defgroup I2C_INT_TYPE
|
||||
* @{
|
||||
*/
|
||||
#define IS_I2C_INT_TYPE(type) (((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_FIFO_ERR_INT) || \
|
||||
((type) == I2C_INT_ALL))
|
||||
#define IS_I2C_INT_TYPE(type) \
|
||||
(((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_FIFO_ERR_INT) || ((type) == I2C_INT_ALL))
|
||||
|
||||
/*@} end of group I2C_Public_Constants */
|
||||
|
||||
@@ -173,22 +163,26 @@ typedef struct
|
||||
#ifndef BFLB_USE_HAL_DRIVER
|
||||
void I2C_IRQHandler(void);
|
||||
#endif
|
||||
void I2C_SendWord(I2C_ID_Type i2cNo, uint32_t data);
|
||||
uint32_t I2C_RecieveWord(I2C_ID_Type i2cNo);
|
||||
void I2C_Enable(I2C_ID_Type i2cNo);
|
||||
void I2C_Disable(I2C_ID_Type i2cNo);
|
||||
void I2C_SendWord(I2C_ID_Type i2cNo, uint32_t data);
|
||||
uint32_t I2C_RecieveWord(I2C_ID_Type i2cNo);
|
||||
void I2C_Enable(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_Reset(I2C_ID_Type i2cNo);
|
||||
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);
|
||||
uint8_t I2C_GetTXFIFOAvailable();
|
||||
uint8_t I2C_GetRXFIFOAvailable();
|
||||
void I2C_DMATxEnable();
|
||||
void I2C_DMATxDisable();
|
||||
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_TransferEndStatus(I2C_ID_Type i2cNo);
|
||||
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);
|
||||
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_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);
|
||||
|
||||
/*@} end of group I2C_Public_Functions */
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ static intCallback_Type *dmaIntCbfArra[DMA_CH_MAX][DMA_INT_ALL] = {
|
||||
{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 */
|
||||
|
||||
@@ -90,14 +90,14 @@ static DMA_LLI_Ctrl_Type PingPongListArra[DMA_CH_MAX][2];
|
||||
* @{
|
||||
*/
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief DMA interrupt handler
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief DMA interrupt handler
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
#ifndef BFLB_USE_HAL_DRIVER
|
||||
void DMA_ALL_IRQHandler(void) {
|
||||
uint32_t tmpVal;
|
||||
@@ -150,14 +150,14 @@ void DMA_ALL_IRQHandler(void) {
|
||||
* @{
|
||||
*/
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief DMA enable
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief DMA enable
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void DMA_Enable(void) {
|
||||
uint32_t tmpVal;
|
||||
/* Get DMA register */
|
||||
@@ -171,14 +171,14 @@ void DMA_Enable(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief DMA disable
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief DMA disable
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void DMA_Disable(void) {
|
||||
uint32_t tmpVal;
|
||||
/* Get DMA register */
|
||||
@@ -189,14 +189,14 @@ void DMA_Disable(void) {
|
||||
BL_WR_REG(DMAChs, DMA_TOP_CONFIG, tmpVal);
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief DMA channel init
|
||||
*
|
||||
* @param chCfg: DMA configuration
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief DMA channel init
|
||||
*
|
||||
* @param chCfg: DMA configuration
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void DMA_Channel_Init(DMA_Channel_Cfg_Type *chCfg) {
|
||||
uint32_t tmpVal;
|
||||
/* 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_TRANS_WIDTH_TYPE(chCfg->srcTransfWidth));
|
||||
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->dstBurstSzie));
|
||||
CHECK_PARAM(IS_DMA_BURST_SIZE_TYPE(chCfg->srcBurstSize));
|
||||
CHECK_PARAM(IS_DMA_BURST_SIZE_TYPE(chCfg->dstBurstSize));
|
||||
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->srcPeriph));
|
||||
|
||||
/* Disable clock gate */
|
||||
// Turns on clock
|
||||
GLB_AHB_Slave1_Clock_Gate(DISABLE, BL_AHB_SLAVE1_DMA);
|
||||
|
||||
/* 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_SWIDTH, chCfg->srcTransfWidth);
|
||||
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_DBSIZE, chCfg->dstBurstSzie);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_SBSIZE, chCfg->srcBurstSize);
|
||||
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_MIN_MODE, chCfg->dstMinMode);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, DMA_FIX_CNT, chCfg->fixCnt);
|
||||
|
||||
/* 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_DI, chCfg->destAddrInc);
|
||||
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_SRCPERIPHERAL, chCfg->srcPeriph);
|
||||
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
|
||||
*
|
||||
* @param ch: DMA channel
|
||||
* @param memAddr: source memoty address
|
||||
* @param len: source memory data length
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief DMA channel update source memory address and len
|
||||
*
|
||||
* @param ch: DMA channel
|
||||
* @param memAddr: source memoty address
|
||||
* @param len: source memory data length
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void DMA_Channel_Update_SrcMemcfg(uint8_t ch, uint32_t memAddr, uint32_t len) {
|
||||
uint32_t tmpVal;
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief DMA channel update destination memory address and len
|
||||
*
|
||||
* @param ch: DMA channel
|
||||
* @param memAddr: destination memoty address
|
||||
* @param len: destination memory data length
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief DMA channel update destination memory address and len
|
||||
*
|
||||
* @param ch: DMA channel
|
||||
* @param memAddr: destination memoty address
|
||||
* @param len: destination memory data length
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void DMA_Channel_Update_DstMemcfg(uint8_t ch, uint32_t memAddr, uint32_t len) {
|
||||
uint32_t tmpVal;
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief Get DMA channel tranfersize
|
||||
*
|
||||
* @param ch: DMA channel
|
||||
*
|
||||
* @return tranfersize size
|
||||
*
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief Get DMA channel tranfersize
|
||||
*
|
||||
* @param ch: DMA channel
|
||||
*
|
||||
* @return tranfersize size
|
||||
*
|
||||
*******************************************************************************/
|
||||
uint32_t DMA_Channel_TranferSize(uint8_t ch) {
|
||||
/* Get channel register */
|
||||
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);
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief Get DMA channel busy status
|
||||
*
|
||||
* @param ch: DMA channel
|
||||
*
|
||||
* @return SET or RESET
|
||||
*
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief Get DMA channel busy status
|
||||
*
|
||||
* @param ch: DMA channel
|
||||
*
|
||||
* @return SET or RESET
|
||||
*
|
||||
*******************************************************************************/
|
||||
BL_Sts_Type DMA_Channel_Is_Busy(uint8_t ch) {
|
||||
/* Get channel register */
|
||||
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;
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief DMA enable
|
||||
*
|
||||
* @param ch: DMA channel number
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief DMA enable
|
||||
*
|
||||
* @param ch: DMA channel number
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void DMA_Channel_Enable(uint8_t ch) {
|
||||
uint32_t tmpVal;
|
||||
/* Get channel register */
|
||||
@@ -350,14 +354,14 @@ void DMA_Channel_Enable(uint8_t ch) {
|
||||
BL_WR_REG(DMAChs, DMA_CONFIG, tmpVal);
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief DMA disable
|
||||
*
|
||||
* @param ch: DMA channel number
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief DMA disable
|
||||
*
|
||||
* @param ch: DMA channel number
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void DMA_Channel_Disable(uint8_t ch) {
|
||||
uint32_t tmpVal;
|
||||
/* Get channel register */
|
||||
@@ -371,15 +375,15 @@ void DMA_Channel_Disable(uint8_t ch) {
|
||||
BL_WR_REG(DMAChs, DMA_CONFIG, tmpVal);
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief DMA init LLI transfer
|
||||
*
|
||||
* @param ch: DMA channel number
|
||||
* @param lliCfg: LLI configuration
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief DMA init LLI transfer
|
||||
*
|
||||
* @param ch: DMA channel number
|
||||
* @param lliCfg: LLI configuration
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void DMA_LLI_Init(uint8_t ch, DMA_LLI_Cfg_Type *lliCfg) {
|
||||
uint32_t tmpVal;
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief DMA channel update LLI
|
||||
*
|
||||
* @param ch: DMA channel number
|
||||
* @param LLI: LLI addr
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief DMA channel update LLI
|
||||
*
|
||||
* @param ch: DMA channel number
|
||||
* @param LLI: LLI addr
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void DMA_LLI_Update(uint8_t ch, uint32_t LLI) {
|
||||
/* Get channel register */
|
||||
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);
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief DMA LLI PingPong Structure Start
|
||||
*
|
||||
* @param dmaPpStruct: dma pp struct pointer
|
||||
* @param Ping_Transfer_len: ping len
|
||||
* @param Pong_Transfer_len: pong len
|
||||
*
|
||||
* @return Succrss or not
|
||||
*
|
||||
*******************************************************************************/
|
||||
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
|
||||
*
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @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) {
|
||||
uint32_t tmpVal;
|
||||
/* 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
|
||||
*
|
||||
* @param dmaChan: DMA Channel type
|
||||
* @param intType: DMA interrupt type
|
||||
* @param cbFun: Pointer to interrupt callback function. The type should be void (*fn)(void)
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief Install DMA interrupt callback function
|
||||
*
|
||||
* @param dmaChan: DMA Channel type
|
||||
* @param intType: DMA interrupt type
|
||||
* @param cbFun: Pointer to interrupt callback function. The type should be void (*fn)(void)
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void DMA_Int_Callback_Install(DMA_Chan_Type dmaChan, DMA_INT_Type intType, intCallback_Type *cbFun) {
|
||||
/* Check the parameters */
|
||||
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;
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @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 */
|
||||
|
||||
@@ -205,11 +205,67 @@ void I2C_Enable(I2C_ID_Type i2cNo) {
|
||||
/* Check the parameters */
|
||||
CHECK_PARAM(IS_I2C_ID_TYPE(i2cNo));
|
||||
|
||||
// Set the M_EN bit
|
||||
|
||||
tmpVal = BL_RD_REG(I2Cx, I2C_CONFIG);
|
||||
tmpVal = BL_SET_REG_BIT(tmpVal, I2C_CR_I2C_M_EN);
|
||||
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
|
||||
}
|
||||
|
||||
uint8_t I2C_GetRXFIFOAvailable() {
|
||||
|
||||
volatile uint32_t tmpVal;
|
||||
uint32_t I2Cx = I2C_BASE;
|
||||
|
||||
tmpVal = BL_RD_REG(I2Cx, I2C_FIFO_CONFIG_1);
|
||||
return (tmpVal >> 8) & 0b11; // Lowest two bits of byte 2
|
||||
}
|
||||
|
||||
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
|
||||
*
|
||||
@@ -297,15 +353,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);
|
||||
}
|
||||
|
||||
// Packet length <=256 bytes per transaction
|
||||
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, I2C_CR_I2C_PKT_LEN, cfg->dataSize - 1);
|
||||
BL_WR_REG(I2Cx, I2C_CONFIG, tmpVal);
|
||||
|
||||
/* Set sub address */
|
||||
BL_WR_REG(I2Cx, I2C_SUB_ADDR, cfg->subAddr);
|
||||
|
||||
#ifndef BFLB_USE_HAL_DRIVER
|
||||
Interrupt_Handler_Register(I2C_IRQn, I2C_IRQHandler);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -491,6 +547,8 @@ BL_Err_Type I2C_MasterSendBlocking(I2C_ID_Type i2cNo, I2C_Transfer_Cfg *cfg) {
|
||||
uint32_t timeOut = 0;
|
||||
uint32_t temp = 0;
|
||||
uint32_t I2Cx = I2C_BASE;
|
||||
I2C_IntMask(I2C0_ID, I2C_TRANS_END_INT, UNMASK); // This function needs to be able to use the irq status bits
|
||||
I2C_IntMask(I2C0_ID, I2C_NACK_RECV_INT, UNMASK); // This function needs to be able to use the irq status bits
|
||||
|
||||
/* Check the parameters */
|
||||
CHECK_PARAM(IS_I2C_ID_TYPE(i2cNo));
|
||||
@@ -571,6 +629,9 @@ BL_Err_Type I2C_MasterReceiveBlocking(I2C_ID_Type i2cNo, I2C_Transfer_Cfg *cfg)
|
||||
I2C_Disable(i2cNo);
|
||||
I2C_Init(i2cNo, I2C_READ, cfg);
|
||||
I2C_Enable(i2cNo);
|
||||
I2C_IntMask(I2C0_ID, I2C_TRANS_END_INT, UNMASK); // This function needs to be able to use the irq status bits
|
||||
I2C_IntMask(I2C0_ID, I2C_NACK_RECV_INT, UNMASK); // This function needs to be able to use the irq status bits
|
||||
|
||||
timeOut = I2C_FIFO_STATUS_TIMEOUT;
|
||||
if (cfg->dataSize == 0 && cfg->subAddrSize == 0) {
|
||||
while (BL_RD_REG(I2C_BASE, I2C_BUS_BUSY)) {
|
||||
@@ -589,6 +650,7 @@ BL_Err_Type I2C_MasterReceiveBlocking(I2C_ID_Type i2cNo, I2C_Transfer_Cfg *cfg)
|
||||
return TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read I2C data */
|
||||
while (cfg->dataSize - i >= 4) {
|
||||
timeOut = I2C_FIFO_STATUS_TIMEOUT;
|
||||
|
||||
@@ -24,9 +24,9 @@ OLED::DisplayState OLED::displayState;
|
||||
int16_t OLED::cursor_x, OLED::cursor_y;
|
||||
bool OLED::initDone = false;
|
||||
uint8_t OLED::displayOffset;
|
||||
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];
|
||||
uint32_t OLED::displayChecksum;
|
||||
alignas(uint32_t) uint8_t OLED::screenBuffer[16 + (OLED_WIDTH * (OLED_HEIGHT / 8)) + 10]; // The data buffer
|
||||
alignas(uint32_t) uint8_t OLED::secondFrameBuffer[16 + (OLED_WIDTH * (OLED_HEIGHT / 8)) + 10];
|
||||
uint32_t OLED::displayChecksum;
|
||||
/*
|
||||
* Setup params for the OLED screen
|
||||
* http://www.displayfuture.com/Display/datasheet/controller/SSD1307.pdf
|
||||
|
||||
@@ -186,6 +186,7 @@ void guiRenderLoop(void) {
|
||||
}
|
||||
// Render done, draw it out
|
||||
OLED::refresh();
|
||||
osDelay(10);
|
||||
}
|
||||
|
||||
OperatingMode handle_post_init_state() {
|
||||
|
||||
@@ -22,12 +22,12 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static TickType_t powerPulseWaitUnit = 25 * TICKS_100MS; // 2.5 s
|
||||
static TickType_t powerPulseDurationUnit = (5 * TICKS_100MS) / 2; // 250 ms
|
||||
TaskHandle_t pidTaskNotification = NULL;
|
||||
volatile TemperatureType_t currentTempTargetDegC = 0; // Current temperature target in C
|
||||
int32_t powerSupplyWattageLimit = 0;
|
||||
bool heaterThermalRunaway = false;
|
||||
static TickType_t powerPulseWaitUnit = 25 * TICKS_100MS; // 2.5 s
|
||||
static TickType_t powerPulseDurationUnit = (5 * TICKS_100MS) / 2; // 250 ms
|
||||
TaskHandle_t pidTaskNotification = NULL;
|
||||
volatile TemperatureType_t currentTempTargetDegC = 0; // Current temperature target in C
|
||||
int32_t powerSupplyWattageLimit = 0;
|
||||
uint8_t heaterThermalRunawayCounter = 0;
|
||||
|
||||
static int32_t getPIDResultX10Watts(TemperatureType_t set_point, TemperatureType_t current_value);
|
||||
static void detectThermalRunaway(const TemperatureType_t currentTipTempInC, const uint32_t x10WattsOut);
|
||||
@@ -71,7 +71,8 @@ void startPIDTask(void const *argument __unused) {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int32_t x10WattsOut = 0;
|
||||
int32_t x10WattsOut = 0;
|
||||
TickType_t lastThermalRunawayDecay = xTaskGetTickCount();
|
||||
|
||||
for (;;) {
|
||||
x10WattsOut = 0;
|
||||
@@ -105,6 +106,12 @@ void startPIDTask(void const *argument __unused) {
|
||||
#ifdef DEBUG_UART_OUTPUT
|
||||
log_system_state(x10WattsOut);
|
||||
#endif
|
||||
if (xTaskGetTickCount() - lastThermalRunawayDecay > TICKS_SECOND) {
|
||||
lastThermalRunawayDecay = xTaskGetTickCount();
|
||||
if (heaterThermalRunawayCounter > 0) {
|
||||
heaterThermalRunawayCounter--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,8 +256,8 @@ void detectThermalRunaway(const TemperatureType_t currentTipTempInC, const uint3
|
||||
static bool haveSeenDelta = false;
|
||||
|
||||
// Check for readings being pegged at the top of the ADC while the heater is off
|
||||
if (!thisCycleIsHeating && (getTipRawTemp(0) > (0x7FFF - 16))) {
|
||||
heaterThermalRunaway = true;
|
||||
if (!thisCycleIsHeating && (getTipRawTemp(0) > (ADC_MAX_READING - 8)) && heaterThermalRunawayCounter < 255) {
|
||||
heaterThermalRunawayCounter++;
|
||||
}
|
||||
|
||||
if (haveSeenDelta) {
|
||||
@@ -277,8 +284,8 @@ void detectThermalRunaway(const TemperatureType_t currentTipTempInC, const uint3
|
||||
TemperatureType_t delta = tipTempMax - tiptempMin;
|
||||
haveSeenDelta = true;
|
||||
|
||||
if (delta < THERMAL_RUNAWAY_TEMP_C) {
|
||||
heaterThermalRunaway = true;
|
||||
if (delta < THERMAL_RUNAWAY_TEMP_C && heaterThermalRunawayCounter < 255) {
|
||||
heaterThermalRunawayCounter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -322,7 +329,7 @@ void setOutputx10WattsViaFilters(int32_t x10WattsOut) {
|
||||
if (getTipRawTemp(0) > (0x7FFF - 32)) {
|
||||
x10WattsOut = 0;
|
||||
}
|
||||
if (heaterThermalRunaway) {
|
||||
if (heaterThermalRunawayCounter > 8) {
|
||||
x10WattsOut = 0;
|
||||
}
|
||||
#ifdef SLEW_LIMIT
|
||||
|
||||
@@ -83,5 +83,5 @@ OperatingMode showWarnings(const ButtonState buttons, guiContext *cxt);
|
||||
// Common helpers
|
||||
int8_t getPowerSourceNumber(void); // Returns number ID of power source
|
||||
|
||||
extern bool heaterThermalRunaway;
|
||||
extern uint8_t heaterThermalRunawayCounter;
|
||||
#endif
|
||||
|
||||
@@ -161,10 +161,10 @@ OperatingMode gui_solderingMode(const ButtonState buttons, guiContext *cxt) {
|
||||
return OperatingMode::Sleeping;
|
||||
}
|
||||
|
||||
if (heaterThermalRunaway) {
|
||||
currentTempTargetDegC = 0; // heater control off
|
||||
heaterThermalRunaway = false;
|
||||
cxt->transitionMode = TransitionAnimation::Right;
|
||||
if (heaterThermalRunawayCounter > 8) {
|
||||
currentTempTargetDegC = 0; // heater control off
|
||||
heaterThermalRunawayCounter = 0;
|
||||
cxt->transitionMode = TransitionAnimation::Right;
|
||||
return OperatingMode::ThermalRunaway;
|
||||
}
|
||||
return handleSolderingButtons(buttons, cxt);
|
||||
|
||||
@@ -159,9 +159,9 @@ OperatingMode gui_solderingProfileMode(const ButtonState buttons, guiContext *cx
|
||||
setBuzzer(false);
|
||||
return OperatingMode::HomeScreen;
|
||||
}
|
||||
if (heaterThermalRunaway) {
|
||||
currentTempTargetDegC = 0; // heater control off
|
||||
heaterThermalRunaway = false;
|
||||
if (heaterThermalRunawayCounter > 8) {
|
||||
currentTempTargetDegC = 0; // heater control off
|
||||
heaterThermalRunawayCounter = 0;
|
||||
return OperatingMode::ThermalRunaway;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "history.hpp"
|
||||
#include "ui_drawing.hpp"
|
||||
|
||||
extern bool heaterThermalRunaway;
|
||||
extern uint8_t heaterThermalRunawayCounter;
|
||||
|
||||
bool checkExitSoldering(void) {
|
||||
#ifdef POW_DC
|
||||
|
||||
Reference in New Issue
Block a user