274 lines
7.4 KiB
C
274 lines
7.4 KiB
C
/**
|
|
* @file sdrv-cam-baremetal-def.h
|
|
*
|
|
* @brief Semidrive platform camera driver and hal adaptive to baremetal 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 "armv7-r/atomic.h"
|
|
#include "armv7-r/cache.h"
|
|
#include "armv7-r/irq.h"
|
|
#include "config.h"
|
|
#include "i2c_cfg.h"
|
|
#include "irq.h"
|
|
#include "irq_num.h"
|
|
#include "regs_base.h"
|
|
#include "sdrv_gpio.h"
|
|
#include "sdrv_i2c.h"
|
|
#include "udelay/udelay.h"
|
|
|
|
// don't use malloc, free
|
|
#define malloc(a) _DO_NOT_USE_MALLOC_IN_BAREMETAL_
|
|
#define free(a)
|
|
// please use ssdk_printf, don't use printf
|
|
#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 uint32_t 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);
|
|
}
|
|
|
|
static inline void mdelay(uint32_t ms)
|
|
{
|
|
while (ms) {
|
|
if (ms < MAX_UDELAY / 1000) {
|
|
udelay(ms * 1000);
|
|
ms = 0;
|
|
} else {
|
|
udelay(MAX_UDELAY);
|
|
ms -= (MAX_UDELAY / 1000);
|
|
}
|
|
}
|
|
}
|
|
|
|
//#define usleep_range(min, max) vTaskDelay(min >> 1)
|
|
static inline void usleep_range(uint32_t min, uint32_t max)
|
|
{
|
|
max = max / 2 + min / 2;
|
|
while (max) {
|
|
if (max < MAX_UDELAY) {
|
|
udelay(max);
|
|
max = 0;
|
|
} else {
|
|
udelay(MAX_UDELAY);
|
|
max -= MAX_UDELAY;
|
|
}
|
|
}
|
|
}
|
|
|
|
inline static void completion_init(completion_t *com)
|
|
{
|
|
com->event = 0;
|
|
}
|
|
|
|
inline static void completion_destroy(completion_t *com)
|
|
{
|
|
com->event = 0;
|
|
}
|
|
|
|
inline static int wait_completion_timeout(completion_t *com, uint32_t timeout)
|
|
{
|
|
if (com == NULL)
|
|
return osErrorParameter;
|
|
while (timeout) {
|
|
if (com->event & CSI_COMPLETE_EVENT_FLAG) {
|
|
com->event &= (~CSI_COMPLETE_EVENT_FLAG);
|
|
return CSI_COMPLETE_EVENT_FLAG;
|
|
}
|
|
//TODO-DELAY
|
|
udelay(1000);
|
|
timeout--;
|
|
}
|
|
return osErrorTimeout;
|
|
}
|
|
|
|
inline static void completion_done(completion_t *com)
|
|
{
|
|
irq_state_t state;
|
|
|
|
if (com == NULL)
|
|
return ;
|
|
state = arch_irq_save();
|
|
com->event |= CSI_COMPLETE_EVENT_FLAG;
|
|
arch_irq_restore(state);
|
|
}
|
|
|
|
// 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) {
|
|
mdelay(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 void *osMutexId_t;
|
|
static inline osMutexId_t osMutexNew(void *p)
|
|
{
|
|
(void)p;
|
|
return NULL;
|
|
}
|
|
|
|
static inline void osMutexDelete(void *p)
|
|
{
|
|
(void)p;
|
|
}
|
|
|
|
static inline void osMutexAcquire(void *p, int t)
|
|
{
|
|
(void)p;
|
|
(void)t;
|
|
}
|
|
|
|
static inline void osMutexRelease(void *p)
|
|
{
|
|
(void)p;
|
|
}
|
|
|
|
#endif /* __SDRV_CAM_OS_DEF_H__ */
|