新增所有文件
This commit is contained in:
353
drivers/include/camera/sdrv-cam-os-def.h
Normal file
353
drivers/include/camera/sdrv-cam-os-def.h
Normal file
@@ -0,0 +1,353 @@
|
||||
/**
|
||||
* @file sdrv-cam-os-def.h
|
||||
*
|
||||
* @brief Semidrive platform camera driver and hal adaptive to operation system header file.
|
||||
*
|
||||
* @copyright Copyright (C) 2021, Semidrive Communications Inc.
|
||||
*
|
||||
* This file is licensed under a dual GPLv2 or X11 license.
|
||||
*
|
||||
*/
|
||||
#ifndef __SDRV_CAM_OS_DEF_H__
|
||||
#define __SDRV_CAM_OS_DEF_H__
|
||||
|
||||
#include <assert.h>
|
||||
#include <bits.h>
|
||||
#include <board.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
#include <lib/list.h>
|
||||
#include <reg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <types.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "armv7-r/atomic.h"
|
||||
#include "armv7-r/cache.h"
|
||||
#include "armv7-r/irq.h"
|
||||
#include "config.h"
|
||||
#include "event_groups.h"
|
||||
#include "i2c_cfg.h"
|
||||
#include "irq.h"
|
||||
#include "irq_num.h"
|
||||
#include "queue.h"
|
||||
#include "regs_base.h"
|
||||
#include "sdrv_gpio.h"
|
||||
#include "sdrv_i2c.h"
|
||||
#include "task.h"
|
||||
|
||||
// define from cmsis_os2.h
|
||||
#define osFlagsWaitAny 0x00000000U ///< Wait for any flag (default).
|
||||
#define osFlagsWaitAll 0x00000001U ///< Wait for all flags.
|
||||
#define osFlagsNoClear 0x00000002U ///< Do not clear flags which have been specified to wait for.
|
||||
#define MAX_BITS_EVENT_GROUPS 24U
|
||||
#define EVENT_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_EVENT_GROUPS) - 1U))
|
||||
|
||||
#define csi_err(x...) ssdk_printf(SSDK_ERR, x)
|
||||
#define csi_warn(x...) ssdk_printf(SSDK_WARNING, x)
|
||||
#define csi_info(x...) ssdk_printf(SSDK_NOTICE, x)
|
||||
#define csi_debug(x...) ssdk_printf(SSDK_DEBUG, x)
|
||||
|
||||
#define cam_err(x...) ssdk_printf(SSDK_ERR, x)
|
||||
#define cam_info(x...) ssdk_printf(SSDK_NOTICE, x)
|
||||
#define cam_debug(x...) ssdk_printf(SSDK_DEBUG, x)
|
||||
|
||||
#define sensor_err(x...) ssdk_printf(SSDK_ERR, x)
|
||||
#define sensor_info(x...) ssdk_printf(SSDK_NOTICE, x)
|
||||
#define sensor_debug(x...) ssdk_printf(SSDK_DEBUG, x)
|
||||
|
||||
#define deser_crit(x...) ssdk_printf(SSDK_CRIT, x)
|
||||
#define deser_err(x...) ssdk_printf(SSDK_ERR, x)
|
||||
#define deser_info(x...) ssdk_printf(SSDK_NOTICE, x)
|
||||
#define deser_debug(x...) ssdk_printf(SSDK_DEBUG, x)
|
||||
|
||||
#define HAL_LOGE(x...) ssdk_printf(SSDK_ERR, x)
|
||||
#define HAL_LOGI(x...) ssdk_printf(SSDK_NOTICE, x)
|
||||
#define HAL_LOGD(x...) ssdk_printf(SSDK_DEBUG, x)
|
||||
|
||||
typedef enum {
|
||||
osOK = 0, ///< Operation completed successfully.
|
||||
osError = -1, ///< Unspecified RTOS error: run-time error but no other error message fits.
|
||||
osErrorTimeout = -2, ///< Operation not completed within the timeout period.
|
||||
osErrorResource = -3, ///< Resource not available.
|
||||
osErrorParameter = -4, ///< Parameter error.
|
||||
osErrorNoMemory = -5, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation.
|
||||
osErrorISR = -6, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines.
|
||||
osStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization.
|
||||
} osStatus_t;
|
||||
|
||||
#ifndef reg_addr_t
|
||||
typedef paddr_t reg_addr_t;
|
||||
#endif
|
||||
|
||||
#ifndef dma_addr_t
|
||||
typedef paddr_t dma_addr_t;
|
||||
#endif
|
||||
|
||||
#define CSI_COMPLETE_EVENT_FLAG 1u
|
||||
|
||||
typedef void *osEventFlagsId_t;
|
||||
typedef struct {
|
||||
osEventFlagsId_t event;
|
||||
} completion_t;
|
||||
|
||||
|
||||
static inline uint32_t reg_read(reg_addr_t base, uint32_t addr)
|
||||
{
|
||||
return readl(base + addr);
|
||||
}
|
||||
|
||||
static inline void reg_write(reg_addr_t base, uint32_t addr, uint32_t val)
|
||||
{
|
||||
writel(val, base + addr);
|
||||
}
|
||||
|
||||
//#define usleep_range(min, max) vTaskDelay(min >> 1)
|
||||
static inline void usleep_range(uint32_t min, uint32_t max)
|
||||
{
|
||||
max = max / 2 + min / 2;
|
||||
if (max < 1000)
|
||||
max = 1000;
|
||||
|
||||
max /= 1000;
|
||||
vTaskDelay(max);
|
||||
}
|
||||
|
||||
#define mdelay(ms) vTaskDelay(ms)
|
||||
#define udelay(us) vTaskDelay((us + 999) / 1000)
|
||||
|
||||
static inline uint32_t IRQ_Context(void)
|
||||
{
|
||||
uint32_t irq;
|
||||
BaseType_t state;
|
||||
|
||||
irq = 0U;
|
||||
|
||||
if (arch_in_irq_mode()) {
|
||||
/* Called from interrupt context */
|
||||
irq = 1U;
|
||||
} else {
|
||||
/* Get FreeRTOS scheduler state */
|
||||
state = xTaskGetSchedulerState();
|
||||
|
||||
if (state != taskSCHEDULER_NOT_STARTED) {
|
||||
/* Scheduler was started */
|
||||
if (arch_irq_is_masked()) {
|
||||
/* Interrupts are masked */
|
||||
irq = 1U;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Return context, 0: thread context, 1: IRQ context */
|
||||
return (irq);
|
||||
}
|
||||
|
||||
inline static void completion_init(completion_t *com)
|
||||
{
|
||||
// com->event = osEventFlagsNew(NULL);
|
||||
EventGroupHandle_t hEventGroup;
|
||||
|
||||
hEventGroup = NULL;
|
||||
if (IRQ_Context() == 0U) { // thread context
|
||||
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||
hEventGroup = xEventGroupCreate();
|
||||
#endif
|
||||
}
|
||||
/* Return event flags ID */
|
||||
com->event = ((osEventFlagsId_t)hEventGroup);
|
||||
}
|
||||
|
||||
inline static void completion_destroy(completion_t *com)
|
||||
{
|
||||
// osEventFlagsDelete(com->event);
|
||||
#ifndef USE_FreeRTOS_HEAP_1
|
||||
if (IRQ_Context() == 0U && com->event != NULL) {
|
||||
vEventGroupDelete(com->event);
|
||||
}
|
||||
return;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline static int wait_completion_timeout(completion_t *com, uint32_t timeout)
|
||||
{
|
||||
// ret = osEventFlagsWait(com->event, CSI_COMPLETE_EVENT_FLAG,
|
||||
// osFlagsWaitAny, timeout);
|
||||
|
||||
uint32_t flags = CSI_COMPLETE_EVENT_FLAG;
|
||||
EventGroupHandle_t hEventGroup = (EventGroupHandle_t)com->event;
|
||||
BaseType_t wait_all;
|
||||
BaseType_t exit_clr;
|
||||
uint32_t rflags;
|
||||
|
||||
if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
|
||||
rflags = (uint32_t)osErrorParameter;
|
||||
} else if (IRQ_Context() != 0U) {
|
||||
rflags = (uint32_t)osErrorISR;
|
||||
} else {
|
||||
wait_all = pdFAIL;
|
||||
exit_clr = pdTRUE;
|
||||
|
||||
rflags = xEventGroupWaitBits(hEventGroup, (EventBits_t)flags, exit_clr,
|
||||
wait_all, (TickType_t)timeout);
|
||||
if ((flags & rflags) == 0U) {
|
||||
if (timeout > 0U) {
|
||||
rflags = (uint32_t)osErrorTimeout;
|
||||
} else {
|
||||
rflags = (uint32_t)osErrorResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (int)rflags;
|
||||
}
|
||||
|
||||
inline static void completion_done(completion_t *com)
|
||||
{
|
||||
// osEventFlagsSet(com->event, CSI_COMPLETE_EVENT_FLAG);
|
||||
EventGroupHandle_t hEventGroup = (EventGroupHandle_t)com->event;
|
||||
BaseType_t yield;
|
||||
|
||||
if ((hEventGroup == NULL) ||
|
||||
((CSI_COMPLETE_EVENT_FLAG & EVENT_FLAGS_INVALID_BITS) != 0U)) {
|
||||
; // rflags = (uint32_t)osErrorParameter;
|
||||
} else if (IRQ_Context() != 0U) {
|
||||
#if (configUSE_OS2_EVENTFLAGS_FROM_ISR == 0)
|
||||
(void)yield;
|
||||
/* Enable timers and xTimerPendFunctionCall function to support
|
||||
* osEventFlagsSet from ISR */
|
||||
// rflags = (uint32_t)osErrorResource;
|
||||
#else
|
||||
yield = pdFALSE;
|
||||
|
||||
if (xEventGroupSetBitsFromISR(hEventGroup,
|
||||
(EventBits_t)CSI_COMPLETE_EVENT_FLAG,
|
||||
&yield) == pdFAIL) {
|
||||
; // rflags = (uint32_t)osErrorResource;
|
||||
} else {
|
||||
// rflags = CSI_COMPLETE_EVENT_FLAG;
|
||||
portYIELD_FROM_ISR(yield);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
xEventGroupSetBits(hEventGroup, (EventBits_t)CSI_COMPLETE_EVENT_FLAG);
|
||||
}
|
||||
/* Return event flags after setting */
|
||||
// return (rflags);
|
||||
}
|
||||
|
||||
// single R5, no need spin lock
|
||||
typedef void *spinlock_t;
|
||||
#define spin_lock_init(a) (*a = NULL)
|
||||
|
||||
#define spin_lock_irqsave(spinlock, flags) \
|
||||
do { \
|
||||
irq_state_t state = arch_irq_save(); \
|
||||
flags = state; \
|
||||
} while (0)
|
||||
|
||||
#define spin_unlock_irqrestore(spinlock, flags) \
|
||||
do { \
|
||||
irq_state_t state = (irq_state_t)flags; \
|
||||
arch_irq_restore(state); \
|
||||
} while (0)
|
||||
|
||||
// gpio_set: set output, and set level to gpio
|
||||
static inline void gpio_set(void *dev, unsigned int pin, bool level)
|
||||
{
|
||||
(void)dev;
|
||||
sdrv_gpio_set_pin_direction(pin, GPIO_DIR_OUT);
|
||||
sdrv_gpio_set_pin_output_level(pin, level);
|
||||
}
|
||||
|
||||
// I2C interface:
|
||||
static inline void wait_idle_and_set_busy(void *ctrl)
|
||||
{
|
||||
sdrv_i2cdrv_bus_stat_t bus_stat;
|
||||
int i = 10;
|
||||
|
||||
bus_stat = sdrv_i2c_get_bus_stat(ctrl);
|
||||
while (bus_stat == SDRV_I2CDRV_BUS_BUSY && i-- > 0) {
|
||||
vTaskDelay(2);
|
||||
bus_stat = sdrv_i2c_get_bus_stat(ctrl);
|
||||
}
|
||||
|
||||
sdrv_i2c_set_bus_stat(ctrl, SDRV_I2CDRV_BUS_BUSY);
|
||||
}
|
||||
|
||||
inline static int i2c_write(void *adap, uint8_t addr, uint8_t *buf, int count)
|
||||
{
|
||||
int ret;
|
||||
|
||||
wait_idle_and_set_busy(adap);
|
||||
sdrv_i2c_write(adap, addr, buf, count, 1000, true);
|
||||
ret = sdrv_i2c_get_trans_stat(adap);
|
||||
sdrv_i2c_set_bus_stat(adap, SDRV_I2CDRV_BUS_IDLE);
|
||||
|
||||
return (ret == SDRV_I2CDRV_TRANS_OK) ? 0 : -1;
|
||||
}
|
||||
|
||||
inline static int i2c_read(void *adap, uint8_t addr, uint8_t *buf, int count)
|
||||
{
|
||||
int ret;
|
||||
|
||||
wait_idle_and_set_busy(adap);
|
||||
sdrv_i2c_read(adap, addr, buf, count, 1000, true);
|
||||
ret = sdrv_i2c_get_trans_stat(adap);
|
||||
sdrv_i2c_set_bus_stat(adap, SDRV_I2CDRV_BUS_IDLE);
|
||||
|
||||
return (ret == SDRV_I2CDRV_TRANS_OK) ? 0 : -1;
|
||||
}
|
||||
|
||||
inline static int i2c_write_read(void *adap, uint8_t addr, uint8_t *reg,
|
||||
int regc, uint8_t *buf, int bufc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
wait_idle_and_set_busy(adap);
|
||||
sdrv_i2c_write(adap, addr, reg, regc, 1000, true);
|
||||
|
||||
ret = sdrv_i2c_get_trans_stat(adap);
|
||||
if (ret == SDRV_I2CDRV_TRANS_OK) {
|
||||
sdrv_i2c_read(adap, addr, buf, bufc, 1000, true);
|
||||
ret = sdrv_i2c_get_trans_stat(adap);
|
||||
}
|
||||
|
||||
sdrv_i2c_set_bus_stat(adap, SDRV_I2CDRV_BUS_IDLE);
|
||||
|
||||
return (ret == SDRV_I2CDRV_TRANS_OK) ? 0 : -1;
|
||||
}
|
||||
|
||||
// mutext
|
||||
typedef QueueHandle_t osMutexId_t;
|
||||
static inline osMutexId_t osMutexNew(void *p)
|
||||
{
|
||||
(void)p;
|
||||
return xQueueCreateMutex(queueQUEUE_TYPE_MUTEX);
|
||||
}
|
||||
|
||||
static inline void osMutexDelete(void *p)
|
||||
{
|
||||
if (p)
|
||||
vQueueDelete(p);
|
||||
}
|
||||
|
||||
static inline void osMutexAcquire(void *p, int t)
|
||||
{
|
||||
(void)p;
|
||||
(void)t;
|
||||
xQueueTakeMutexRecursive(p, t);
|
||||
}
|
||||
|
||||
static inline void osMutexRelease(void *p)
|
||||
{
|
||||
(void)p;
|
||||
xQueueGiveMutexRecursive(p);
|
||||
}
|
||||
|
||||
#endif /* __SDRV_CAM_OS_DEF_H__ */
|
||||
Reference in New Issue
Block a user