From deec768bb279505c5e05dd7701a6635c736bb391 Mon Sep 17 00:00:00 2001 From: SEEKFREE_Kang Date: Wed, 15 Apr 2020 20:07:26 +0800 Subject: [PATCH] =?UTF-8?q?V1.0.2=20=20=E4=BF=AE=E6=94=B9=E6=A8=A1?= =?UTF-8?q?=E6=8B=9FIIC=E9=BB=98=E8=AE=A4=E5=BB=B6=E6=97=B6=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E4=B8=BA20=20=20=E6=B7=BB=E5=8A=A0=20=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E7=89=B9=E5=88=AB=E6=B3=A8=E6=84=8FP20=5F2=E6=98=AF?= =?UTF-8?q?=E4=B8=8D=E8=83=BD=E7=94=A8=E4=BA=8E=E8=BE=93=E5=87=BA=E7=9A=84?= =?UTF-8?q?=EF=BC=8C=E4=BB=85=E4=BB=85=E5=8F=AA=E6=9C=89=E8=BE=93=E5=85=A5?= =?UTF-8?q?=E7=9A=84=E5=8A=9F=E8=83=BD=20=E6=B3=A8=E6=84=8F=E4=BA=8B?= =?UTF-8?q?=E9=A1=B9=20=20=E5=B0=86=E6=91=84=E5=83=8F=E5=A4=B4=E9=87=87?= =?UTF-8?q?=E9=9B=86DMA=E6=94=B9=E4=B8=BAlink=E4=BC=A0=E8=BE=93=EF=BC=8C?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E5=A4=A7=E5=A4=A7=E9=99=8D=E4=BD=8EDMA?= =?UTF-8?q?=E4=B8=AD=E6=96=AD=E6=AC=A1=E6=95=B0=20=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E7=9A=84=E8=BD=AF=E4=BB=B6IIC=E5=BC=95?= =?UTF-8?q?=E8=84=9A=E5=AE=9A=E4=B9=89=20=20=E5=B0=866050=E7=AD=89=20?= =?UTF-8?q?=E9=9C=80=E8=A6=81=E7=94=A8=E5=88=B0=E8=BD=AF=E4=BB=B6IIC?= =?UTF-8?q?=E7=9A=84=E6=A8=A1=E5=9D=97=EF=BC=8C=E5=9C=A8=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E5=87=BD=E6=95=B0=E4=B8=AD=E9=BB=98=E8=AE=A4=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E6=A8=A1=E6=8B=9FIIC=E5=88=9D=E5=A7=8B=E5=8C=96=20=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=B0=8F=E9=92=BB=E9=A3=8E=E9=A9=B1=E5=8A=A8?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Example/1-ADC_Demo/Libraries/doc/version.txt | 12 +- .../seekfree_libraries/common/common.c | 2 +- .../seekfree_libraries/common/common.h | 2 +- .../Libraries/seekfree_libraries/headfile.h | 1 + .../Libraries/seekfree_libraries/zf_eru_dma.c | 87 +++++- .../Libraries/seekfree_libraries/zf_eru_dma.h | 4 +- .../Libraries/seekfree_libraries/zf_gpio.c | 1 + .../Libraries/seekfree_libraries/zf_gpio.h | 9 + .../seekfree_peripheral/SEEKFREE_7725.c | 262 ++++++++++++++++++ .../seekfree_peripheral/SEEKFREE_7725.h | 243 ++++++++++++++++ .../seekfree_peripheral/SEEKFREE_ICM20602.c | 1 + .../seekfree_peripheral/SEEKFREE_IIC.c | 2 +- .../seekfree_peripheral/SEEKFREE_IIC.h | 8 +- .../seekfree_peripheral/SEEKFREE_L3G4200D.c | 1 + .../seekfree_peripheral/SEEKFREE_MMA8451.c | 1 + .../seekfree_peripheral/SEEKFREE_MPU6050.c | 1 + .../seekfree_peripheral/SEEKFREE_MT9V03X.c | 24 +- .../seekfree_peripheral/SEEKFREE_MT9V03X.h | 4 +- Example/1-ADC_Demo/USER/isr.c | 6 +- .../Libraries/doc/version.txt | 12 +- .../seekfree_libraries/common/common.c | 2 +- .../seekfree_libraries/common/common.h | 2 +- .../Libraries/seekfree_libraries/headfile.h | 1 + .../Libraries/seekfree_libraries/zf_eru_dma.c | 87 +++++- .../Libraries/seekfree_libraries/zf_eru_dma.h | 4 +- .../Libraries/seekfree_libraries/zf_gpio.c | 1 + .../Libraries/seekfree_libraries/zf_gpio.h | 9 + .../seekfree_peripheral/SEEKFREE_7725.c | 262 ++++++++++++++++++ .../seekfree_peripheral/SEEKFREE_7725.h | 243 ++++++++++++++++ .../seekfree_peripheral/SEEKFREE_ICM20602.c | 1 + .../seekfree_peripheral/SEEKFREE_IIC.c | 2 +- .../seekfree_peripheral/SEEKFREE_IIC.h | 8 +- .../seekfree_peripheral/SEEKFREE_L3G4200D.c | 1 + .../seekfree_peripheral/SEEKFREE_MMA8451.c | 1 + .../seekfree_peripheral/SEEKFREE_MPU6050.c | 1 + .../seekfree_peripheral/SEEKFREE_MT9V03X.c | 24 +- .../seekfree_peripheral/SEEKFREE_MT9V03X.h | 4 +- .../10-Interrupt_Priority_Set_Demo/USER/isr.c | 6 +- .../11-Systick_Demo/Libraries/doc/version.txt | 12 +- .../seekfree_libraries/common/common.c | 2 +- .../seekfree_libraries/common/common.h | 2 +- .../Libraries/seekfree_libraries/headfile.h | 1 + .../Libraries/seekfree_libraries/zf_eru_dma.c | 87 +++++- .../Libraries/seekfree_libraries/zf_eru_dma.h | 4 +- .../Libraries/seekfree_libraries/zf_gpio.c | 1 + .../Libraries/seekfree_libraries/zf_gpio.h | 9 + .../seekfree_peripheral/SEEKFREE_7725.c | 262 ++++++++++++++++++ .../seekfree_peripheral/SEEKFREE_7725.h | 243 ++++++++++++++++ .../seekfree_peripheral/SEEKFREE_ICM20602.c | 1 + .../seekfree_peripheral/SEEKFREE_IIC.c | 2 +- .../seekfree_peripheral/SEEKFREE_IIC.h | 8 +- .../seekfree_peripheral/SEEKFREE_L3G4200D.c | 1 + .../seekfree_peripheral/SEEKFREE_MMA8451.c | 1 + .../seekfree_peripheral/SEEKFREE_MPU6050.c | 1 + .../seekfree_peripheral/SEEKFREE_MT9V03X.c | 24 +- .../seekfree_peripheral/SEEKFREE_MT9V03X.h | 4 +- Example/11-Systick_Demo/USER/isr.c | 6 +- .../Libraries/doc/version.txt | 12 +- .../seekfree_libraries/common/common.c | 2 +- .../seekfree_libraries/common/common.h | 2 +- .../Libraries/seekfree_libraries/headfile.h | 1 + .../Libraries/seekfree_libraries/zf_eru_dma.c | 87 +++++- .../Libraries/seekfree_libraries/zf_eru_dma.h | 4 +- .../Libraries/seekfree_libraries/zf_gpio.c | 1 + .../Libraries/seekfree_libraries/zf_gpio.h | 9 + .../seekfree_peripheral/SEEKFREE_7725.c | 262 ++++++++++++++++++ .../seekfree_peripheral/SEEKFREE_7725.h | 243 ++++++++++++++++ .../seekfree_peripheral/SEEKFREE_ICM20602.c | 1 + .../seekfree_peripheral/SEEKFREE_IIC.c | 2 +- .../seekfree_peripheral/SEEKFREE_IIC.h | 8 +- .../seekfree_peripheral/SEEKFREE_L3G4200D.c | 1 + .../seekfree_peripheral/SEEKFREE_MMA8451.c | 1 + .../seekfree_peripheral/SEEKFREE_MPU6050.c | 1 + .../seekfree_peripheral/SEEKFREE_MT9V03X.c | 24 +- .../seekfree_peripheral/SEEKFREE_MT9V03X.h | 4 +- Example/12-Dual_Core_Demo/USER/isr.c | 6 +- .../Libraries/doc/version.txt | 12 +- .../seekfree_libraries/common/common.c | 2 +- .../seekfree_libraries/common/common.h | 2 +- .../Libraries/seekfree_libraries/headfile.h | 1 + .../Libraries/seekfree_libraries/zf_eru_dma.c | 87 +++++- .../Libraries/seekfree_libraries/zf_eru_dma.h | 4 +- .../Libraries/seekfree_libraries/zf_gpio.c | 1 + .../Libraries/seekfree_libraries/zf_gpio.h | 9 + .../seekfree_peripheral/SEEKFREE_7725.c | 262 ++++++++++++++++++ .../seekfree_peripheral/SEEKFREE_7725.h | 243 ++++++++++++++++ .../seekfree_peripheral/SEEKFREE_ICM20602.c | 1 + .../seekfree_peripheral/SEEKFREE_IIC.c | 2 +- .../seekfree_peripheral/SEEKFREE_IIC.h | 8 +- .../seekfree_peripheral/SEEKFREE_L3G4200D.c | 1 + .../seekfree_peripheral/SEEKFREE_MMA8451.c | 1 + .../seekfree_peripheral/SEEKFREE_MPU6050.c | 1 + .../seekfree_peripheral/SEEKFREE_MT9V03X.c | 24 +- .../seekfree_peripheral/SEEKFREE_MT9V03X.h | 4 +- Example/2-LED_Blink_Demo/USER/isr.c | 6 +- Example/3-PIT_Demo/Libraries/doc/version.txt | 12 +- .../seekfree_libraries/common/common.c | 2 +- .../seekfree_libraries/common/common.h | 2 +- .../Libraries/seekfree_libraries/headfile.h | 1 + .../Libraries/seekfree_libraries/zf_eru_dma.c | 87 +++++- .../Libraries/seekfree_libraries/zf_eru_dma.h | 4 +- .../Libraries/seekfree_libraries/zf_gpio.c | 1 + .../Libraries/seekfree_libraries/zf_gpio.h | 9 + .../seekfree_peripheral/SEEKFREE_7725.c | 262 ++++++++++++++++++ .../seekfree_peripheral/SEEKFREE_7725.h | 243 ++++++++++++++++ .../seekfree_peripheral/SEEKFREE_ICM20602.c | 1 + .../seekfree_peripheral/SEEKFREE_IIC.c | 2 +- .../seekfree_peripheral/SEEKFREE_IIC.h | 8 +- .../seekfree_peripheral/SEEKFREE_L3G4200D.c | 1 + .../seekfree_peripheral/SEEKFREE_MMA8451.c | 1 + .../seekfree_peripheral/SEEKFREE_MPU6050.c | 1 + .../seekfree_peripheral/SEEKFREE_MT9V03X.c | 24 +- .../seekfree_peripheral/SEEKFREE_MT9V03X.h | 4 +- Example/3-PIT_Demo/USER/isr.c | 10 +- .../4-Encoder_Demo/Libraries/doc/version.txt | 12 +- .../seekfree_libraries/common/common.c | 2 +- .../seekfree_libraries/common/common.h | 2 +- .../Libraries/seekfree_libraries/headfile.h | 1 + .../Libraries/seekfree_libraries/zf_eru_dma.c | 87 +++++- .../Libraries/seekfree_libraries/zf_eru_dma.h | 4 +- .../Libraries/seekfree_libraries/zf_gpio.c | 1 + .../Libraries/seekfree_libraries/zf_gpio.h | 9 + .../seekfree_peripheral/SEEKFREE_7725.c | 262 ++++++++++++++++++ .../seekfree_peripheral/SEEKFREE_7725.h | 243 ++++++++++++++++ .../seekfree_peripheral/SEEKFREE_ICM20602.c | 1 + .../seekfree_peripheral/SEEKFREE_IIC.c | 2 +- .../seekfree_peripheral/SEEKFREE_IIC.h | 8 +- .../seekfree_peripheral/SEEKFREE_L3G4200D.c | 1 + .../seekfree_peripheral/SEEKFREE_MMA8451.c | 1 + .../seekfree_peripheral/SEEKFREE_MPU6050.c | 1 + .../seekfree_peripheral/SEEKFREE_MT9V03X.c | 24 +- .../seekfree_peripheral/SEEKFREE_MT9V03X.h | 4 +- Example/4-Encoder_Demo/USER/isr.c | 6 +- Example/5-UART_Demo/Libraries/doc/version.txt | 12 +- .../seekfree_libraries/common/common.c | 2 +- .../seekfree_libraries/common/common.h | 2 +- .../Libraries/seekfree_libraries/headfile.h | 1 + .../Libraries/seekfree_libraries/zf_eru_dma.c | 87 +++++- .../Libraries/seekfree_libraries/zf_eru_dma.h | 4 +- .../Libraries/seekfree_libraries/zf_gpio.c | 1 + .../Libraries/seekfree_libraries/zf_gpio.h | 9 + .../seekfree_peripheral/SEEKFREE_7725.c | 262 ++++++++++++++++++ .../seekfree_peripheral/SEEKFREE_7725.h | 243 ++++++++++++++++ .../seekfree_peripheral/SEEKFREE_ICM20602.c | 1 + .../seekfree_peripheral/SEEKFREE_IIC.c | 2 +- .../seekfree_peripheral/SEEKFREE_IIC.h | 8 +- .../seekfree_peripheral/SEEKFREE_L3G4200D.c | 1 + .../seekfree_peripheral/SEEKFREE_MMA8451.c | 1 + .../seekfree_peripheral/SEEKFREE_MPU6050.c | 1 + .../seekfree_peripheral/SEEKFREE_MT9V03X.c | 24 +- .../seekfree_peripheral/SEEKFREE_MT9V03X.h | 4 +- Example/5-UART_Demo/USER/isr.c | 6 +- .../6-Printf_Demo/Libraries/doc/version.txt | 12 +- .../seekfree_libraries/common/common.c | 2 +- .../seekfree_libraries/common/common.h | 2 +- .../Libraries/seekfree_libraries/headfile.h | 1 + .../Libraries/seekfree_libraries/zf_eru_dma.c | 87 +++++- .../Libraries/seekfree_libraries/zf_eru_dma.h | 4 +- .../Libraries/seekfree_libraries/zf_gpio.c | 1 + .../Libraries/seekfree_libraries/zf_gpio.h | 9 + .../seekfree_peripheral/SEEKFREE_7725.c | 262 ++++++++++++++++++ .../seekfree_peripheral/SEEKFREE_7725.h | 243 ++++++++++++++++ .../seekfree_peripheral/SEEKFREE_ICM20602.c | 1 + .../seekfree_peripheral/SEEKFREE_IIC.c | 2 +- .../seekfree_peripheral/SEEKFREE_IIC.h | 8 +- .../seekfree_peripheral/SEEKFREE_L3G4200D.c | 1 + .../seekfree_peripheral/SEEKFREE_MMA8451.c | 1 + .../seekfree_peripheral/SEEKFREE_MPU6050.c | 1 + .../seekfree_peripheral/SEEKFREE_MT9V03X.c | 24 +- .../seekfree_peripheral/SEEKFREE_MT9V03X.h | 4 +- Example/6-Printf_Demo/USER/isr.c | 6 +- .../Libraries/doc/version.txt | 12 +- .../seekfree_libraries/common/common.c | 2 +- .../seekfree_libraries/common/common.h | 2 +- .../Libraries/seekfree_libraries/headfile.h | 1 + .../Libraries/seekfree_libraries/zf_eru_dma.c | 87 +++++- .../Libraries/seekfree_libraries/zf_eru_dma.h | 4 +- .../Libraries/seekfree_libraries/zf_gpio.c | 1 + .../Libraries/seekfree_libraries/zf_gpio.h | 9 + .../seekfree_peripheral/SEEKFREE_7725.c | 262 ++++++++++++++++++ .../seekfree_peripheral/SEEKFREE_7725.h | 243 ++++++++++++++++ .../seekfree_peripheral/SEEKFREE_ICM20602.c | 1 + .../seekfree_peripheral/SEEKFREE_IIC.c | 2 +- .../seekfree_peripheral/SEEKFREE_IIC.h | 8 +- .../seekfree_peripheral/SEEKFREE_L3G4200D.c | 1 + .../seekfree_peripheral/SEEKFREE_MMA8451.c | 1 + .../seekfree_peripheral/SEEKFREE_MPU6050.c | 1 + .../seekfree_peripheral/SEEKFREE_MT9V03X.c | 24 +- .../seekfree_peripheral/SEEKFREE_MT9V03X.h | 4 +- Example/7-GPIO_Interrupt_Demo/USER/isr.c | 10 +- .../8-EEPROM_Demo/Libraries/doc/version.txt | 12 +- .../seekfree_libraries/common/common.c | 2 +- .../seekfree_libraries/common/common.h | 2 +- .../Libraries/seekfree_libraries/headfile.h | 1 + .../Libraries/seekfree_libraries/zf_eru_dma.c | 87 +++++- .../Libraries/seekfree_libraries/zf_eru_dma.h | 4 +- .../Libraries/seekfree_libraries/zf_gpio.c | 1 + .../Libraries/seekfree_libraries/zf_gpio.h | 9 + .../seekfree_peripheral/SEEKFREE_7725.c | 262 ++++++++++++++++++ .../seekfree_peripheral/SEEKFREE_7725.h | 243 ++++++++++++++++ .../seekfree_peripheral/SEEKFREE_ICM20602.c | 1 + .../seekfree_peripheral/SEEKFREE_IIC.c | 2 +- .../seekfree_peripheral/SEEKFREE_IIC.h | 8 +- .../seekfree_peripheral/SEEKFREE_L3G4200D.c | 1 + .../seekfree_peripheral/SEEKFREE_MMA8451.c | 1 + .../seekfree_peripheral/SEEKFREE_MPU6050.c | 1 + .../seekfree_peripheral/SEEKFREE_MT9V03X.c | 24 +- .../seekfree_peripheral/SEEKFREE_MT9V03X.h | 4 +- Example/8-EEPROM_Demo/USER/isr.c | 6 +- Example/9-PWM_Demo/Libraries/doc/version.txt | 12 +- .../seekfree_libraries/common/common.c | 2 +- .../seekfree_libraries/common/common.h | 2 +- .../Libraries/seekfree_libraries/headfile.h | 1 + .../Libraries/seekfree_libraries/zf_eru_dma.c | 87 +++++- .../Libraries/seekfree_libraries/zf_eru_dma.h | 4 +- .../Libraries/seekfree_libraries/zf_gpio.c | 1 + .../Libraries/seekfree_libraries/zf_gpio.h | 9 + .../seekfree_peripheral/SEEKFREE_7725.c | 262 ++++++++++++++++++ .../seekfree_peripheral/SEEKFREE_7725.h | 243 ++++++++++++++++ .../seekfree_peripheral/SEEKFREE_ICM20602.c | 1 + .../seekfree_peripheral/SEEKFREE_IIC.c | 2 +- .../seekfree_peripheral/SEEKFREE_IIC.h | 8 +- .../seekfree_peripheral/SEEKFREE_L3G4200D.c | 1 + .../seekfree_peripheral/SEEKFREE_MMA8451.c | 1 + .../seekfree_peripheral/SEEKFREE_MPU6050.c | 1 + .../seekfree_peripheral/SEEKFREE_MT9V03X.c | 24 +- .../seekfree_peripheral/SEEKFREE_MT9V03X.h | 4 +- Example/9-PWM_Demo/USER/isr.c | 6 +- .../Libraries/doc/version.txt | 12 +- .../seekfree_libraries/common/common.c | 2 +- .../seekfree_libraries/common/common.h | 2 +- .../Libraries/seekfree_libraries/headfile.h | 1 + .../Libraries/seekfree_libraries/zf_eru_dma.c | 87 +++++- .../Libraries/seekfree_libraries/zf_eru_dma.h | 4 +- .../Libraries/seekfree_libraries/zf_gpio.c | 1 + .../Libraries/seekfree_libraries/zf_gpio.h | 9 + .../seekfree_peripheral/SEEKFREE_7725.c | 262 ++++++++++++++++++ .../seekfree_peripheral/SEEKFREE_7725.h | 243 ++++++++++++++++ .../seekfree_peripheral/SEEKFREE_ICM20602.c | 1 + .../seekfree_peripheral/SEEKFREE_IIC.c | 2 +- .../seekfree_peripheral/SEEKFREE_IIC.h | 8 +- .../seekfree_peripheral/SEEKFREE_L3G4200D.c | 1 + .../seekfree_peripheral/SEEKFREE_MMA8451.c | 1 + .../seekfree_peripheral/SEEKFREE_MPU6050.c | 1 + .../seekfree_peripheral/SEEKFREE_MT9V03X.c | 24 +- .../seekfree_peripheral/SEEKFREE_MT9V03X.h | 4 +- .../USER/Cpu0_Main.c | 1 - Seekfree_TC264_Opensource_Library/USER/isr.c | 6 +- .../逐飞科技 TASKING使用说明书 V1.0.pdf | Bin 1480522 -> 0 bytes .../逐飞科技 TASKING使用说明书.pdf | Bin 0 -> 1450308 bytes 250 files changed, 8242 insertions(+), 490 deletions(-) create mode 100644 Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c create mode 100644 Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h create mode 100644 Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c create mode 100644 Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h create mode 100644 Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c create mode 100644 Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h create mode 100644 Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c create mode 100644 Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h create mode 100644 Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c create mode 100644 Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h create mode 100644 Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c create mode 100644 Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h create mode 100644 Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c create mode 100644 Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h create mode 100644 Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c create mode 100644 Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h create mode 100644 Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c create mode 100644 Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h create mode 100644 Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c create mode 100644 Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h create mode 100644 Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c create mode 100644 Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h create mode 100644 Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c create mode 100644 Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h create mode 100644 Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_7725.c create mode 100644 Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_7725.h delete mode 100644 【文档】TASKING使用教程 芯片手册等/逐飞科技 TASKING使用说明书 V1.0.pdf create mode 100644 【文档】TASKING使用教程 芯片手册等/逐飞科技 TASKING使用说明书.pdf diff --git a/Example/1-ADC_Demo/Libraries/doc/version.txt b/Example/1-ADC_Demo/Libraries/doc/version.txt index b85cd50..a42bc58 100644 --- a/Example/1-ADC_Demo/Libraries/doc/version.txt +++ b/Example/1-ADC_Demo/Libraries/doc/version.txt @@ -1,9 +1,17 @@ V1.0.0 - ʼ汾 + ʼ汾 V1.0.1 ͷijжϽ޸ģжϱ־λΪ0Ųɼһͼ񣬱ַʳͻ ޸SPIʼеĴ˹̶SPI2ַ ޸STM޷ʹSTM1 - ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ \ No newline at end of file + ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ + +V1.0.2 + ޸ģIICĬʱʱΪ20 + ҪرעP20_2DzģֻĹ ע + ͷɼDMAΪlink䣬Դ󽵵DMAжϴ + ޸ĬϵIICŶ + 6050 ҪõIICģ飬ڳʼĬϵģIICʼ + С \ No newline at end of file diff --git a/Example/1-ADC_Demo/Libraries/seekfree_libraries/common/common.c b/Example/1-ADC_Demo/Libraries/seekfree_libraries/common/common.c index 0460d15..ac42b19 100644 --- a/Example/1-ADC_Demo/Libraries/seekfree_libraries/common/common.c +++ b/Example/1-ADC_Demo/Libraries/seekfree_libraries/common/common.c @@ -22,7 +22,7 @@ #include "SysSe/Bsp/Bsp.h" #include "common.h" -uint8 camera_type; +uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С diff --git a/Example/1-ADC_Demo/Libraries/seekfree_libraries/common/common.h b/Example/1-ADC_Demo/Libraries/seekfree_libraries/common/common.h index fe7ec63..13d03cd 100644 --- a/Example/1-ADC_Demo/Libraries/seekfree_libraries/common/common.h +++ b/Example/1-ADC_Demo/Libraries/seekfree_libraries/common/common.h @@ -111,7 +111,7 @@ typedef enum //ö #include -extern uint8 camera_type; +extern uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С void get_clk(void); diff --git a/Example/1-ADC_Demo/Libraries/seekfree_libraries/headfile.h b/Example/1-ADC_Demo/Libraries/seekfree_libraries/headfile.h index 0e8024f..e11bd83 100644 --- a/Example/1-ADC_Demo/Libraries/seekfree_libraries/headfile.h +++ b/Example/1-ADC_Demo/Libraries/seekfree_libraries/headfile.h @@ -62,6 +62,7 @@ #include "SEEKFREE_L3G4200D.h" #include "SEEKFREE_WIRELESS.h" #include "SEEKFREE_IPS200_PARALLEL8.h" +#include "SEEKFREE_7725.h" #endif diff --git a/Example/1-ADC_Demo/Libraries/seekfree_libraries/zf_eru_dma.c b/Example/1-ADC_Demo/Libraries/seekfree_libraries/zf_eru_dma.c index f7aab10..86c0158 100644 --- a/Example/1-ADC_Demo/Libraries/seekfree_libraries/zf_eru_dma.c +++ b/Example/1-ADC_Demo/Libraries/seekfree_libraries/zf_eru_dma.c @@ -21,9 +21,18 @@ #include "IfxDma_Dma.h" #include "IfxScuEru.h" #include "isr_config.h" +#include "zf_assert.h" #include "zf_eru_dma.h" +typedef struct +{ + Ifx_DMA_CH IFX_ALIGN(256) linked_list[8];//DMA + IfxDma_Dma_Channel channel; //DMAͨ +}DMA_LINK; + + +DMA_LINK dma_link_list; //------------------------------------------------------------------------------------------------------------------- // @brief erudmaʼ @@ -36,7 +45,7 @@ // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) { IfxDma_Dma_Channel dmaChn; //eruDMAͨ eruļeruȼΪͨ @@ -51,27 +60,85 @@ void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destinatio IfxDma_Dma_ChannelConfig cfg; IfxDma_Dma_initChannelConfig(&cfg, &dma); - cfg.transferCount = dma_count; + uint8 list_num, i; + uint16 single_channel_dma_count; + + ZF_ASSERT(!(dma_count%8));//Ϊ8ı + + + list_num = 1; + single_channel_dma_count = dma_count / list_num; + if(16384 < single_channel_dma_count) + { + while(TRUE) + { + single_channel_dma_count = dma_count / list_num; + if((single_channel_dma_count <= 16384) && !(dma_count % list_num)) + { + break; + } + list_num++; + if(list_num > 8) ZF_ASSERT(FALSE); + } + } + + + if(1 == list_num) + { + cfg.shadowControl = IfxDma_ChannelShadow_none; + cfg.operationMode = IfxDma_ChannelOperationMode_single; + cfg.shadowAddress = 0; + } + else + { + cfg.shadowControl = IfxDma_ChannelShadow_linkedList; + cfg.operationMode = IfxDma_ChannelOperationMode_continuous; + cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[1]); + } + cfg.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest; cfg.moveSize = IfxDma_ChannelMoveSize_8bit; + cfg.busPriority = IfxDma_ChannelBusPriority_high; - cfg.busPriority = IfxDma_ChannelBusPriority_high; - - cfg.sourceAddress = (unsigned)(source_addr); + cfg.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), source_addr); cfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_none; cfg.sourceCircularBufferEnabled = TRUE; - cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); cfg.destinationAddressIncrementStep = IfxDma_ChannelIncrementStep_1; - cfg.operationMode = IfxDma_ChannelOperationMode_single; - cfg.channelId = (IfxDma_ChannelId)dma_ch; - cfg.hardwareRequestEnabled = TRUE; - cfg.channelInterruptEnabled = TRUE; + cfg.channelId = (IfxDma_ChannelId)dma_ch; + cfg.hardwareRequestEnabled = FALSE; + cfg.channelInterruptEnabled = TRUE; cfg.channelInterruptPriority = ERU_DMA_INT_PRIO; cfg.channelInterruptTypeOfService = (IfxSrc_Tos)ERU_DMA_INT_SERVICE; + + + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); + + cfg.transferCount = single_channel_dma_count; + IfxDma_Dma_initChannel(&dmaChn, &cfg); + + if(1 < list_num) + { + i = 0; + while(i < list_num) + { + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr + single_channel_dma_count * i); + if(i == (list_num - 1)) cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[0]); + else cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[i+1]); + cfg.transferCount = single_channel_dma_count; + + IfxDma_Dma_initLinkedListEntry((void *)&dma_link_list.linked_list[i], &cfg); + i++; + } + } + + + IfxDma_Dma_getSrcPointer(&dma_link_list.channel)->B.CLRR = 1; + + return list_num; } diff --git a/Example/1-ADC_Demo/Libraries/seekfree_libraries/zf_eru_dma.h b/Example/1-ADC_Demo/Libraries/seekfree_libraries/zf_eru_dma.h index 50667ad..faef169 100644 --- a/Example/1-ADC_Demo/Libraries/seekfree_libraries/zf_eru_dma.h +++ b/Example/1-ADC_Demo/Libraries/seekfree_libraries/zf_eru_dma.h @@ -29,9 +29,9 @@ #define CLEAR_DMA_FLAG(dma_ch) IfxDma_clearChannelInterrupt(&MODULE_DMA, dma_ch); -#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)destination_addr) +#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr)) -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); void dma_stop(IfxDma_ChannelId dma_ch); void dma_start(IfxDma_ChannelId dma_ch); diff --git a/Example/1-ADC_Demo/Libraries/seekfree_libraries/zf_gpio.c b/Example/1-ADC_Demo/Libraries/seekfree_libraries/zf_gpio.c index 3c937cf..1d2466c 100644 --- a/Example/1-ADC_Demo/Libraries/seekfree_libraries/zf_gpio.c +++ b/Example/1-ADC_Demo/Libraries/seekfree_libraries/zf_gpio.c @@ -60,6 +60,7 @@ Ifx_P* get_port(PIN_enum pin) // @param pinmode ãòzf_gpio.hļGPIOMODE_enumöֵȷ // @return void // Sample usage: gpio_init(P00_0, GPO, 1, PUSHPULL);//P00_0ʼΪGPIOܡģʽߵƽ +// @note ҪرעP20_2DzģֻĹ //------------------------------------------------------------------------------------------------------------------- void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinmode) { diff --git a/Example/1-ADC_Demo/Libraries/seekfree_libraries/zf_gpio.h b/Example/1-ADC_Demo/Libraries/seekfree_libraries/zf_gpio.h index cfbd666..e3d144f 100644 --- a/Example/1-ADC_Demo/Libraries/seekfree_libraries/zf_gpio.h +++ b/Example/1-ADC_Demo/Libraries/seekfree_libraries/zf_gpio.h @@ -38,6 +38,15 @@ typedef enum // ö #define GET_PORT_IN_ADDR(pin) (uint8 *)(&IfxPort_getAddress((IfxPort_Index)(pin/32))->IN + pin%32/8) + + +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ + + + + //------------------------------------------------------ //ͨGPIO void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinconf); diff --git a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c new file mode 100644 index 0000000..806b8d9 --- /dev/null +++ b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c @@ -0,0 +1,262 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + +#include "IfxDma.h" +#include "IfxScuEru.h" +#include "zf_stm_systick.h" +#include "zf_gpio.h" +#include "zf_eru.h" +#include "zf_eru_dma.h" +#include "SEEKFREE_IIC.h" +#include "SEEKFREE_7725.h" + + + +IFX_ALIGN(4) uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +uint8 image_dec[OV7725_H][OV7725_W]; + +uint8 ov7725_idcode = 0; + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷڲĴʼ(ڲʹãû) +// @param NULL +// @return uint8 01ɹ +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_reg_init(void) +{ + simiic_delay_set(500); + simiic_write_reg ( OV7725_DEV_ADD, OV7725_COM7, 0x80 ); //λͷ + systick_delay_ms(STM0, 50); + ov7725_idcode = simiic_read_reg( OV7725_DEV_ADD, OV7725_VER ,SCCB); + if( ov7725_idcode != OV7725_ID ) return 0; //УͷID + + //IDȷ ȻüĴ + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM4 , 0xC1); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CLKRC , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM2 , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM3 , 0xD0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM7 , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM8 , 0xCE); //0xCE:رԶع 0xCFԶع + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSTART , 0x3F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSIZE , 0x50); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSTRT , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSIZE , 0x78); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HREF , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SCAL0 , 0x0A); + simiic_write_reg(OV7725_DEV_ADD, OV7725_AWB_Ctrl0 , 0xE0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSPAuto , 0xff); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl2 , 0x0C); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl3 , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl4 , 0x00); + + if(OV7725_W == 80) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x14); + else if(OV7725_W == 160) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x28); + else if(OV7725_W == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x3c); + else if(OV7725_W == 320) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x50); + + if(OV7725_H == 60) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x1E); + else if(OV7725_H == 120) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x3c); + else if(OV7725_H == 180) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x5a); + else if(OV7725_H == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x78); + + simiic_write_reg(OV7725_DEV_ADD, OV7725_REG28 , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCH , 0x10); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCL , 0x1F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM1 , 0x0c); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM2 , 0x16); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM3 , 0x2a); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM4 , 0x4e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM5 , 0x61); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM6 , 0x6f); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM7 , 0x7b); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM8 , 0x86); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM9 , 0x8e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM10 , 0x97); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM11 , 0xa4); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM12 , 0xaf); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM13 , 0xc5); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM14 , 0xd7); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM15 , 0xe8); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SLOP , 0x20); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_RADI , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEF , 0x13); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_XC , 0x08); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFB , 0x14); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFR , 0x17); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_CTR , 0x05); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDBase , 0x99); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDMStep , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SDE , 0x04); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BRIGHT , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CNST , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SIGN , 0x06); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ0 , 0x11); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ1 , 0x02); + + + simiic_delay_set(SIMIIC_DELAY_TIME);//޸ΪĬϵ20 + return 1; + + +} + + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷɼʼ(ڲʹãû) +// @param NULL +// @return void +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +void ov7725_port_init(void) +{ + uint8 i; + camera_type = 3;//ͷ + + //ͷɼʼ + //ʼ + for(i=0; i<8; i++) + { + gpio_init((PIN_enum)(OV7725_DATA_PIN+i), GPI, 0, PULLUP); + } + eru_dma_init(OV7725_DMA_CH, GET_PORT_IN_ADDR(OV7725_DATA_PIN), image_bin[0], OV7725_PCLK_PIN, FALLING, OV7725_DMA_NUM); + eru_init(OV7725_VSYNC_PIN, FALLING); //ʼжϣΪ½شж + +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷʼ(֮úжϺɲɼͼ) +// @param NULL +// @return 0 +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_init(void) +{ + simiic_init(); + ov7725_reg_init(); //ͷĴ + ov7725_port_init(); //ͷжżDMA + return 0; +} + + + + +uint8 ov7725_finish_flag = 0; +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбeruGPIOжϣжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_vsync(void) +{ + CLEAR_GPIO_FLAG(OV7725_VSYNC_PIN); + + if(!ov7725_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ + { + DMA_SET_DESTINATION(OV7725_DMA_CH, image_bin[0]); + dma_start(OV7725_DMA_CH); + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷDMAж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбdmaжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_dma(void) +{ + CLEAR_DMA_FLAG(OV7725_DMA_CH); + ov7725_finish_flag = 1; + dma_stop(OV7725_DMA_CH); +} + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷݽѹ +// @param *data1 Դַ +// @param *data2 Ŀĵַ +// @return void +// @since v1.0 +// Sample usage: Image_Decompression(da1,dat2[0]);//һάdat1ݽѹάdat2. +//------------------------------------------------------------------------------------------------------------------- +void image_decompression(uint8 *data1,uint8 *data2) +{ + uint8 temp[2] = {0,255}; + uint16 lenth = OV7725_SIZE; + uint8 i = 8; + + + while(lenth--) + { + i = 8; + while(i--) + { + *data2++ = temp[(*data1 >> i) & 0x01]; + } + data1++; + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷδѹͼλ鿴ͼ +// @param *imgaddr ѹͼݵַ +// @param *imgsize ͼС(ֱдOV7725_SIZE) +// @return void +// @since v1.0 +// Sample usage: øúǰȳʼuart2 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_sendimg_7725(UARTN_enum uartn) +{ + uart_putchar(uartn, 0x00);uart_putchar(uartn, 0xff);uart_putchar(uartn, 0x01);uart_putchar(uartn, 0x01);//ĸֽ + uart_putbuff(uartn, image_bin[0], OV7725_SIZE); //ٷͼ +} + + + + diff --git a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h new file mode 100644 index 0000000..e513250 --- /dev/null +++ b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h @@ -0,0 +1,243 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + + +#ifndef _SEEKFREE_7725_h +#define _SEEKFREE_7725_h + +#include "common.h" +#include "IfxDma_cfg.h" +#include "zf_uart.h" + + +//ͷID +#define OV7725_ID 0x21 + +//ͷĴ +#define OV7725_GAIN 0x00 +#define OV7725_BLUE 0x01 +#define OV7725_RED 0x02 +#define OV7725_GREEN 0x03 +#define OV7725_BAVG 0x05 +#define OV7725_GAVG 0x06 +#define OV7725_RAVG 0x07 +#define OV7725_AECH 0x08 +#define OV7725_COM2 0x09 +#define OV7725_PID 0x0A +#define OV7725_VER 0x0B +#define OV7725_COM3 0x0C +#define OV7725_COM4 0x0D +#define OV7725_COM5 0x0E +#define OV7725_COM6 0x0F +#define OV7725_AEC 0x10 +#define OV7725_CLKRC 0x11 +#define OV7725_COM7 0x12 +#define OV7725_COM8 0x13 +#define OV7725_COM9 0x14 +#define OV7725_COM10 0x15 +#define OV7725_REG16 0x16 +#define OV7725_HSTART 0x17 +#define OV7725_HSIZE 0x18 +#define OV7725_VSTRT 0x19 +#define OV7725_VSIZE 0x1A +#define OV7725_PSHFT 0x1B +#define OV7725_MIDH 0x1C +#define OV7725_MIDL 0x1D +#define OV7725_LAEC 0x1F +#define OV7725_COM11 0x20 +#define OV7725_BDBase 0x22 +#define OV7725_BDMStep 0x23 +#define OV7725_AEW 0x24 +#define OV7725_AEB 0x25 +#define OV7725_VPT 0x26 +#define OV7725_REG28 0x28 +#define OV7725_HOutSize 0x29 +#define OV7725_EXHCH 0x2A +#define OV7725_EXHCL 0x2B +#define OV7725_VOutSize 0x2C +#define OV7725_ADVFL 0x2D +#define OV7725_ADVFH 0x2E +#define OV7725_YAVE 0x2F +#define OV7725_LumHTh 0x30 +#define OV7725_LumLTh 0x31 +#define OV7725_HREF 0x32 +#define OV7725_DM_LNL 0x33 +#define OV7725_DM_LNH 0x34 +#define OV7725_ADoff_B 0x35 +#define OV7725_ADoff_R 0x36 +#define OV7725_ADoff_Gb 0x37 +#define OV7725_ADoff_Gr 0x38 +#define OV7725_Off_B 0x39 +#define OV7725_Off_R 0x3A +#define OV7725_Off_Gb 0x3B +#define OV7725_Off_Gr 0x3C +#define OV7725_COM12 0x3D +#define OV7725_COM13 0x3E +#define OV7725_COM14 0x3F +#define OV7725_COM16 0x41 +#define OV7725_TGT_B 0x42 +#define OV7725_TGT_R 0x43 +#define OV7725_TGT_Gb 0x44 +#define OV7725_TGT_Gr 0x45 +#define OV7725_LC_CTR 0x46 +#define OV7725_LC_XC 0x47 +#define OV7725_LC_YC 0x48 +#define OV7725_LC_COEF 0x49 +#define OV7725_LC_RADI 0x4A +#define OV7725_LC_COEFB 0x4B +#define OV7725_LC_COEFR 0x4C +#define OV7725_FixGain 0x4D +#define OV7725_AREF1 0x4F +#define OV7725_AREF6 0x54 +#define OV7725_UFix 0x60 +#define OV7725_VFix 0x61 +#define OV7725_AWBb_blk 0x62 +#define OV7725_AWB_Ctrl0 0x63 +#define OV7725_DSP_Ctrl1 0x64 +#define OV7725_DSP_Ctrl2 0x65 +#define OV7725_DSP_Ctrl3 0x66 +#define OV7725_DSP_Ctrl4 0x67 +#define OV7725_AWB_bias 0x68 +#define OV7725_AWBCtrl1 0x69 +#define OV7725_AWBCtrl2 0x6A +#define OV7725_AWBCtrl3 0x6B +#define OV7725_AWBCtrl4 0x6C +#define OV7725_AWBCtrl5 0x6D +#define OV7725_AWBCtrl6 0x6E +#define OV7725_AWBCtrl7 0x6F +#define OV7725_AWBCtrl8 0x70 +#define OV7725_AWBCtrl9 0x71 +#define OV7725_AWBCtrl10 0x72 +#define OV7725_AWBCtrl11 0x73 +#define OV7725_AWBCtrl12 0x74 +#define OV7725_AWBCtrl13 0x75 +#define OV7725_AWBCtrl14 0x76 +#define OV7725_AWBCtrl15 0x77 +#define OV7725_AWBCtrl16 0x78 +#define OV7725_AWBCtrl17 0x79 +#define OV7725_AWBCtrl18 0x7A +#define OV7725_AWBCtrl19 0x7B +#define OV7725_AWBCtrl20 0x7C +#define OV7725_AWBCtrl21 0x7D +#define OV7725_GAM1 0x7E +#define OV7725_GAM2 0x7F +#define OV7725_GAM3 0x80 +#define OV7725_GAM4 0x81 +#define OV7725_GAM5 0x82 +#define OV7725_GAM6 0x83 +#define OV7725_GAM7 0x84 +#define OV7725_GAM8 0x85 +#define OV7725_GAM9 0x86 +#define OV7725_GAM10 0x87 +#define OV7725_GAM11 0x88 +#define OV7725_GAM12 0x89 +#define OV7725_GAM13 0x8A +#define OV7725_GAM14 0x8B +#define OV7725_GAM15 0x8C +#define OV7725_SLOP 0x8D +#define OV7725_DNSTh 0x8E +#define OV7725_EDGE0 0x8F +#define OV7725_EDGE1 0x90 +#define OV7725_DNSOff 0x91 +#define OV7725_EDGE2 0x92 +#define OV7725_EDGE3 0x93 +#define OV7725_MTX1 0x94 +#define OV7725_MTX2 0x95 +#define OV7725_MTX3 0x96 +#define OV7725_MTX4 0x97 +#define OV7725_MTX5 0x98 +#define OV7725_MTX6 0x99 +#define OV7725_MTX_Ctrl 0x9A +#define OV7725_BRIGHT 0x9B +#define OV7725_CNST 0x9C +#define OV7725_UVADJ0 0x9E +#define OV7725_UVADJ1 0x9F +#define OV7725_SCAL0 0xA0 +#define OV7725_SCAL1 0xA1 +#define OV7725_SCAL2 0xA2 +#define OV7725_SDE 0xA6 +#define OV7725_USAT 0xA7 +#define OV7725_VSAT 0xA8 +#define OV7725_HUECOS 0xA9 +#define OV7725_HUESIN 0xAA +#define OV7725_SIGN 0xAB +#define OV7725_DSPAuto 0xAC + + +#define OV7725_DEV_ADD 0x42>>1 + + +//ͷ +#define OV7725_W 160 //ͷͼ ò 80 160 240 320 +#define OV7725_H 120 //ͷͼ߶ ò 60 120 180 240 +#define OV7725_SIZE (OV7725_W * OV7725_H/8 ) //ͼռÿռС +#define OV7725_DMA_NUM (OV7725_SIZE) //һͼDMAɼ + + +//-------------------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------------------- +#define OV7725_VSYNC_PIN ERU_CH3_REQ6_P02_0 //ж ѡΧοERU_PIN_enumö ѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DATA_PIN P00_0 //D0 D0ΪP00_0 ôD1ʹõΪP00_1 + //òP00_0P02_0P15_0Ϊ + +#define OV7725_PCLK_PIN ERU_CH2_REQ14_P02_1 //ʱ ѡΧοERU_PIN_enumö 볡жѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ + //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 + + + +extern uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +extern uint8 image_dec[OV7725_H][OV7725_W]; //ͼѹ + +extern uint8 ov7725_finish_flag; //ͼɼɱ־λ + + +// +uint8 ov7725_init(void); +void ov7725_vsync(void); +void ov7725_dma(void); +void image_decompression(uint8 *data1,uint8 *data2); +void seekfree_sendimg_7725(UARTN_enum uartn); + + + +#endif + + + diff --git a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c index 095f9e3..5d167c9 100644 --- a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c +++ b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c @@ -68,6 +68,7 @@ void icm20602_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void icm20602_init(void) { + simiic_init(); systick_delay_ms(STM0, 10); //ϵʱ // diff --git a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c index 196fd57..f56a41a 100644 --- a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c +++ b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c @@ -50,7 +50,7 @@ uint8 IIC_num; // -static uint16 simiic_delay_time=100; //ICMȴӦΪ100 +static uint16 simiic_delay_time = SIMIIC_DELAY_TIME; //ICMȴӦΪ20 //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h index 293a02a..6a9c1e3 100644 --- a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h +++ b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h @@ -34,8 +34,12 @@ -#define SEEKFREE_SCL P13_0 //SCL ΪIO -#define SEEKFREE_SDA P13_1 //SDA ΪIO +#define SEEKFREE_SCL P02_3 //SCL ΪIO +#define SEEKFREE_SDA P02_2 //SDA ΪIO + + +#define SIMIIC_DELAY_TIME 20 + typedef enum IIC //DACģ { diff --git a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c index 0f0c23a..5deb7d3 100644 --- a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c +++ b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c @@ -65,6 +65,7 @@ void l3g4200d_self_check(void) //------------------------------------------------------------------------------------------------------------------- void l3g4200d_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); l3g4200d_self_check(); diff --git a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c index c200427..8a5eec4 100644 --- a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c +++ b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c @@ -68,6 +68,7 @@ void mma8451_self_check(void) //------------------------------------------------------------------------------------------------------------------- uint8 mma845x_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); mma8451_self_check(); diff --git a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c index 0317aa0..686550d 100644 --- a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c +++ b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c @@ -71,6 +71,7 @@ void mpu6050_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void mpu6050_init(void) { + simiic_init(); systick_delay_ms(STM0, 100); //ϵʱ mpu6050_self1_check(); diff --git a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c index 014b435..05f181f 100644 --- a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c +++ b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c @@ -38,7 +38,6 @@ #include "zf_gpio.h" #include "zf_eru.h" #include "zf_eru_dma.h" -#include "stdio.h" #include "SEEKFREE_MT9V03X.h" @@ -49,6 +48,8 @@ uint8 receive[3]; uint8 receive_num = 0; vuint8 uart_receive_flag; +uint8 link_list_num; + //Ҫõͷ int16 MT9V03X_CFG[CONFIG_FINISH][2]= { @@ -305,7 +306,7 @@ void mt9v03x_init(void) gpio_init((PIN_enum)(MT9V03X_DATA_PIN+i), GPI, 0, PULLUP); } - eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W); + link_list_num = eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W*MT9V03X_H); eru_init(MT9V03X_VSYNC_PIN, FALLING); //ʼжϣΪ½شж restoreInterrupts(interrupt_state); @@ -313,7 +314,6 @@ void mt9v03x_init(void) uint8 mt9v03x_finish_flag = 0; //һͼɼɱ־λ -uint8 now_col; //ǰڲɼ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03Xͷж // @param NULL @@ -324,16 +324,15 @@ uint8 now_col; // void mt9v03x_vsync(void) { CLEAR_GPIO_FLAG(MT9V03X_VSYNC_PIN); - now_col = 0; + if(!mt9v03x_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ { - DMA_SET_DESTINATION(MT9V03X_DMA_CH, (void *)&mt9v03x_image[0]); dma_start(MT9V03X_DMA_CH); } } - +uint8 mt9v03x_dma_int_num; //ǰDMAжϴ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03XͷDMAж // @param NULL @@ -344,16 +343,15 @@ void mt9v03x_vsync(void) void mt9v03x_dma(void) { CLEAR_DMA_FLAG(MT9V03X_DMA_CH); + mt9v03x_dma_int_num++; - now_col++; - - if(MT9V03X_H > now_col) - { - dma_start(MT9V03X_DMA_CH); - } - else + if(mt9v03x_dma_int_num >= link_list_num) { + //ɼ + mt9v03x_dma_int_num = 0; mt9v03x_finish_flag = 1;//һͼӲɼʼɼʱ3.8MS(50FPS188*120ֱ) + dma_stop(MT9V03X_DMA_CH); + } } diff --git a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h index a29edd2..0c8a785 100644 --- a/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h +++ b/Example/1-ADC_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h @@ -63,9 +63,7 @@ //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ #define MT9V03X_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ - //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 - - + //ͷö typedef enum { diff --git a/Example/1-ADC_Demo/USER/isr.c b/Example/1-ADC_Demo/USER/isr.c index 15666f2..c6376b0 100644 --- a/Example/1-ADC_Demo/USER/isr.c +++ b/Example/1-ADC_Demo/USER/isr.c @@ -98,7 +98,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) if(GET_GPIO_FLAG(ERU_CH3_REQ6_P02_0))//ͨ3ж { CLEAR_GPIO_FLAG(ERU_CH3_REQ6_P02_0); - if(1 == camera_type)mt9v03x_vsync(); + if (1 == camera_type) mt9v03x_vsync(); + else if (3 == camera_type) ov7725_vsync(); } if(GET_GPIO_FLAG(ERU_CH7_REQ16_P15_1))//ͨ7ж @@ -113,7 +114,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) IFX_INTERRUPT(dma_ch5_isr, ERU_DMA_INT_SERVICE, ERU_DMA_INT_PRIO) { - if(1 == camera_type) mt9v03x_dma(); + if (1 == camera_type) mt9v03x_dma(); + else if (3 == camera_type) ov7725_dma(); } diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/doc/version.txt b/Example/10-Interrupt_Priority_Set_Demo/Libraries/doc/version.txt index b85cd50..a42bc58 100644 --- a/Example/10-Interrupt_Priority_Set_Demo/Libraries/doc/version.txt +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/doc/version.txt @@ -1,9 +1,17 @@ V1.0.0 - ʼ汾 + ʼ汾 V1.0.1 ͷijжϽ޸ģжϱ־λΪ0Ųɼһͼ񣬱ַʳͻ ޸SPIʼеĴ˹̶SPI2ַ ޸STM޷ʹSTM1 - ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ \ No newline at end of file + ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ + +V1.0.2 + ޸ģIICĬʱʱΪ20 + ҪرעP20_2DzģֻĹ ע + ͷɼDMAΪlink䣬Դ󽵵DMAжϴ + ޸ĬϵIICŶ + 6050 ҪõIICģ飬ڳʼĬϵģIICʼ + С \ No newline at end of file diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/common/common.c b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/common/common.c index 0460d15..ac42b19 100644 --- a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/common/common.c +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/common/common.c @@ -22,7 +22,7 @@ #include "SysSe/Bsp/Bsp.h" #include "common.h" -uint8 camera_type; +uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/common/common.h b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/common/common.h index fe7ec63..13d03cd 100644 --- a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/common/common.h +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/common/common.h @@ -111,7 +111,7 @@ typedef enum //ö #include -extern uint8 camera_type; +extern uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С void get_clk(void); diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/headfile.h b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/headfile.h index 0e8024f..e11bd83 100644 --- a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/headfile.h +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/headfile.h @@ -62,6 +62,7 @@ #include "SEEKFREE_L3G4200D.h" #include "SEEKFREE_WIRELESS.h" #include "SEEKFREE_IPS200_PARALLEL8.h" +#include "SEEKFREE_7725.h" #endif diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/zf_eru_dma.c b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/zf_eru_dma.c index f7aab10..86c0158 100644 --- a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/zf_eru_dma.c +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/zf_eru_dma.c @@ -21,9 +21,18 @@ #include "IfxDma_Dma.h" #include "IfxScuEru.h" #include "isr_config.h" +#include "zf_assert.h" #include "zf_eru_dma.h" +typedef struct +{ + Ifx_DMA_CH IFX_ALIGN(256) linked_list[8];//DMA + IfxDma_Dma_Channel channel; //DMAͨ +}DMA_LINK; + + +DMA_LINK dma_link_list; //------------------------------------------------------------------------------------------------------------------- // @brief erudmaʼ @@ -36,7 +45,7 @@ // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) { IfxDma_Dma_Channel dmaChn; //eruDMAͨ eruļeruȼΪͨ @@ -51,27 +60,85 @@ void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destinatio IfxDma_Dma_ChannelConfig cfg; IfxDma_Dma_initChannelConfig(&cfg, &dma); - cfg.transferCount = dma_count; + uint8 list_num, i; + uint16 single_channel_dma_count; + + ZF_ASSERT(!(dma_count%8));//Ϊ8ı + + + list_num = 1; + single_channel_dma_count = dma_count / list_num; + if(16384 < single_channel_dma_count) + { + while(TRUE) + { + single_channel_dma_count = dma_count / list_num; + if((single_channel_dma_count <= 16384) && !(dma_count % list_num)) + { + break; + } + list_num++; + if(list_num > 8) ZF_ASSERT(FALSE); + } + } + + + if(1 == list_num) + { + cfg.shadowControl = IfxDma_ChannelShadow_none; + cfg.operationMode = IfxDma_ChannelOperationMode_single; + cfg.shadowAddress = 0; + } + else + { + cfg.shadowControl = IfxDma_ChannelShadow_linkedList; + cfg.operationMode = IfxDma_ChannelOperationMode_continuous; + cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[1]); + } + cfg.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest; cfg.moveSize = IfxDma_ChannelMoveSize_8bit; + cfg.busPriority = IfxDma_ChannelBusPriority_high; - cfg.busPriority = IfxDma_ChannelBusPriority_high; - - cfg.sourceAddress = (unsigned)(source_addr); + cfg.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), source_addr); cfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_none; cfg.sourceCircularBufferEnabled = TRUE; - cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); cfg.destinationAddressIncrementStep = IfxDma_ChannelIncrementStep_1; - cfg.operationMode = IfxDma_ChannelOperationMode_single; - cfg.channelId = (IfxDma_ChannelId)dma_ch; - cfg.hardwareRequestEnabled = TRUE; - cfg.channelInterruptEnabled = TRUE; + cfg.channelId = (IfxDma_ChannelId)dma_ch; + cfg.hardwareRequestEnabled = FALSE; + cfg.channelInterruptEnabled = TRUE; cfg.channelInterruptPriority = ERU_DMA_INT_PRIO; cfg.channelInterruptTypeOfService = (IfxSrc_Tos)ERU_DMA_INT_SERVICE; + + + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); + + cfg.transferCount = single_channel_dma_count; + IfxDma_Dma_initChannel(&dmaChn, &cfg); + + if(1 < list_num) + { + i = 0; + while(i < list_num) + { + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr + single_channel_dma_count * i); + if(i == (list_num - 1)) cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[0]); + else cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[i+1]); + cfg.transferCount = single_channel_dma_count; + + IfxDma_Dma_initLinkedListEntry((void *)&dma_link_list.linked_list[i], &cfg); + i++; + } + } + + + IfxDma_Dma_getSrcPointer(&dma_link_list.channel)->B.CLRR = 1; + + return list_num; } diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/zf_eru_dma.h b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/zf_eru_dma.h index 50667ad..faef169 100644 --- a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/zf_eru_dma.h +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/zf_eru_dma.h @@ -29,9 +29,9 @@ #define CLEAR_DMA_FLAG(dma_ch) IfxDma_clearChannelInterrupt(&MODULE_DMA, dma_ch); -#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)destination_addr) +#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr)) -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); void dma_stop(IfxDma_ChannelId dma_ch); void dma_start(IfxDma_ChannelId dma_ch); diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/zf_gpio.c b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/zf_gpio.c index 3c937cf..1d2466c 100644 --- a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/zf_gpio.c +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/zf_gpio.c @@ -60,6 +60,7 @@ Ifx_P* get_port(PIN_enum pin) // @param pinmode ãòzf_gpio.hļGPIOMODE_enumöֵȷ // @return void // Sample usage: gpio_init(P00_0, GPO, 1, PUSHPULL);//P00_0ʼΪGPIOܡģʽߵƽ +// @note ҪرעP20_2DzģֻĹ //------------------------------------------------------------------------------------------------------------------- void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinmode) { diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/zf_gpio.h b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/zf_gpio.h index cfbd666..e3d144f 100644 --- a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/zf_gpio.h +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_libraries/zf_gpio.h @@ -38,6 +38,15 @@ typedef enum // ö #define GET_PORT_IN_ADDR(pin) (uint8 *)(&IfxPort_getAddress((IfxPort_Index)(pin/32))->IN + pin%32/8) + + +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ + + + + //------------------------------------------------------ //ͨGPIO void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinconf); diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c new file mode 100644 index 0000000..806b8d9 --- /dev/null +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c @@ -0,0 +1,262 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + +#include "IfxDma.h" +#include "IfxScuEru.h" +#include "zf_stm_systick.h" +#include "zf_gpio.h" +#include "zf_eru.h" +#include "zf_eru_dma.h" +#include "SEEKFREE_IIC.h" +#include "SEEKFREE_7725.h" + + + +IFX_ALIGN(4) uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +uint8 image_dec[OV7725_H][OV7725_W]; + +uint8 ov7725_idcode = 0; + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷڲĴʼ(ڲʹãû) +// @param NULL +// @return uint8 01ɹ +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_reg_init(void) +{ + simiic_delay_set(500); + simiic_write_reg ( OV7725_DEV_ADD, OV7725_COM7, 0x80 ); //λͷ + systick_delay_ms(STM0, 50); + ov7725_idcode = simiic_read_reg( OV7725_DEV_ADD, OV7725_VER ,SCCB); + if( ov7725_idcode != OV7725_ID ) return 0; //УͷID + + //IDȷ ȻüĴ + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM4 , 0xC1); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CLKRC , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM2 , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM3 , 0xD0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM7 , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM8 , 0xCE); //0xCE:رԶع 0xCFԶع + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSTART , 0x3F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSIZE , 0x50); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSTRT , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSIZE , 0x78); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HREF , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SCAL0 , 0x0A); + simiic_write_reg(OV7725_DEV_ADD, OV7725_AWB_Ctrl0 , 0xE0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSPAuto , 0xff); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl2 , 0x0C); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl3 , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl4 , 0x00); + + if(OV7725_W == 80) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x14); + else if(OV7725_W == 160) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x28); + else if(OV7725_W == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x3c); + else if(OV7725_W == 320) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x50); + + if(OV7725_H == 60) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x1E); + else if(OV7725_H == 120) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x3c); + else if(OV7725_H == 180) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x5a); + else if(OV7725_H == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x78); + + simiic_write_reg(OV7725_DEV_ADD, OV7725_REG28 , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCH , 0x10); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCL , 0x1F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM1 , 0x0c); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM2 , 0x16); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM3 , 0x2a); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM4 , 0x4e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM5 , 0x61); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM6 , 0x6f); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM7 , 0x7b); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM8 , 0x86); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM9 , 0x8e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM10 , 0x97); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM11 , 0xa4); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM12 , 0xaf); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM13 , 0xc5); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM14 , 0xd7); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM15 , 0xe8); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SLOP , 0x20); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_RADI , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEF , 0x13); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_XC , 0x08); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFB , 0x14); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFR , 0x17); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_CTR , 0x05); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDBase , 0x99); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDMStep , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SDE , 0x04); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BRIGHT , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CNST , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SIGN , 0x06); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ0 , 0x11); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ1 , 0x02); + + + simiic_delay_set(SIMIIC_DELAY_TIME);//޸ΪĬϵ20 + return 1; + + +} + + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷɼʼ(ڲʹãû) +// @param NULL +// @return void +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +void ov7725_port_init(void) +{ + uint8 i; + camera_type = 3;//ͷ + + //ͷɼʼ + //ʼ + for(i=0; i<8; i++) + { + gpio_init((PIN_enum)(OV7725_DATA_PIN+i), GPI, 0, PULLUP); + } + eru_dma_init(OV7725_DMA_CH, GET_PORT_IN_ADDR(OV7725_DATA_PIN), image_bin[0], OV7725_PCLK_PIN, FALLING, OV7725_DMA_NUM); + eru_init(OV7725_VSYNC_PIN, FALLING); //ʼжϣΪ½شж + +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷʼ(֮úжϺɲɼͼ) +// @param NULL +// @return 0 +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_init(void) +{ + simiic_init(); + ov7725_reg_init(); //ͷĴ + ov7725_port_init(); //ͷжżDMA + return 0; +} + + + + +uint8 ov7725_finish_flag = 0; +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбeruGPIOжϣжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_vsync(void) +{ + CLEAR_GPIO_FLAG(OV7725_VSYNC_PIN); + + if(!ov7725_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ + { + DMA_SET_DESTINATION(OV7725_DMA_CH, image_bin[0]); + dma_start(OV7725_DMA_CH); + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷDMAж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбdmaжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_dma(void) +{ + CLEAR_DMA_FLAG(OV7725_DMA_CH); + ov7725_finish_flag = 1; + dma_stop(OV7725_DMA_CH); +} + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷݽѹ +// @param *data1 Դַ +// @param *data2 Ŀĵַ +// @return void +// @since v1.0 +// Sample usage: Image_Decompression(da1,dat2[0]);//һάdat1ݽѹάdat2. +//------------------------------------------------------------------------------------------------------------------- +void image_decompression(uint8 *data1,uint8 *data2) +{ + uint8 temp[2] = {0,255}; + uint16 lenth = OV7725_SIZE; + uint8 i = 8; + + + while(lenth--) + { + i = 8; + while(i--) + { + *data2++ = temp[(*data1 >> i) & 0x01]; + } + data1++; + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷδѹͼλ鿴ͼ +// @param *imgaddr ѹͼݵַ +// @param *imgsize ͼС(ֱдOV7725_SIZE) +// @return void +// @since v1.0 +// Sample usage: øúǰȳʼuart2 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_sendimg_7725(UARTN_enum uartn) +{ + uart_putchar(uartn, 0x00);uart_putchar(uartn, 0xff);uart_putchar(uartn, 0x01);uart_putchar(uartn, 0x01);//ĸֽ + uart_putbuff(uartn, image_bin[0], OV7725_SIZE); //ٷͼ +} + + + + diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h new file mode 100644 index 0000000..e513250 --- /dev/null +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h @@ -0,0 +1,243 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + + +#ifndef _SEEKFREE_7725_h +#define _SEEKFREE_7725_h + +#include "common.h" +#include "IfxDma_cfg.h" +#include "zf_uart.h" + + +//ͷID +#define OV7725_ID 0x21 + +//ͷĴ +#define OV7725_GAIN 0x00 +#define OV7725_BLUE 0x01 +#define OV7725_RED 0x02 +#define OV7725_GREEN 0x03 +#define OV7725_BAVG 0x05 +#define OV7725_GAVG 0x06 +#define OV7725_RAVG 0x07 +#define OV7725_AECH 0x08 +#define OV7725_COM2 0x09 +#define OV7725_PID 0x0A +#define OV7725_VER 0x0B +#define OV7725_COM3 0x0C +#define OV7725_COM4 0x0D +#define OV7725_COM5 0x0E +#define OV7725_COM6 0x0F +#define OV7725_AEC 0x10 +#define OV7725_CLKRC 0x11 +#define OV7725_COM7 0x12 +#define OV7725_COM8 0x13 +#define OV7725_COM9 0x14 +#define OV7725_COM10 0x15 +#define OV7725_REG16 0x16 +#define OV7725_HSTART 0x17 +#define OV7725_HSIZE 0x18 +#define OV7725_VSTRT 0x19 +#define OV7725_VSIZE 0x1A +#define OV7725_PSHFT 0x1B +#define OV7725_MIDH 0x1C +#define OV7725_MIDL 0x1D +#define OV7725_LAEC 0x1F +#define OV7725_COM11 0x20 +#define OV7725_BDBase 0x22 +#define OV7725_BDMStep 0x23 +#define OV7725_AEW 0x24 +#define OV7725_AEB 0x25 +#define OV7725_VPT 0x26 +#define OV7725_REG28 0x28 +#define OV7725_HOutSize 0x29 +#define OV7725_EXHCH 0x2A +#define OV7725_EXHCL 0x2B +#define OV7725_VOutSize 0x2C +#define OV7725_ADVFL 0x2D +#define OV7725_ADVFH 0x2E +#define OV7725_YAVE 0x2F +#define OV7725_LumHTh 0x30 +#define OV7725_LumLTh 0x31 +#define OV7725_HREF 0x32 +#define OV7725_DM_LNL 0x33 +#define OV7725_DM_LNH 0x34 +#define OV7725_ADoff_B 0x35 +#define OV7725_ADoff_R 0x36 +#define OV7725_ADoff_Gb 0x37 +#define OV7725_ADoff_Gr 0x38 +#define OV7725_Off_B 0x39 +#define OV7725_Off_R 0x3A +#define OV7725_Off_Gb 0x3B +#define OV7725_Off_Gr 0x3C +#define OV7725_COM12 0x3D +#define OV7725_COM13 0x3E +#define OV7725_COM14 0x3F +#define OV7725_COM16 0x41 +#define OV7725_TGT_B 0x42 +#define OV7725_TGT_R 0x43 +#define OV7725_TGT_Gb 0x44 +#define OV7725_TGT_Gr 0x45 +#define OV7725_LC_CTR 0x46 +#define OV7725_LC_XC 0x47 +#define OV7725_LC_YC 0x48 +#define OV7725_LC_COEF 0x49 +#define OV7725_LC_RADI 0x4A +#define OV7725_LC_COEFB 0x4B +#define OV7725_LC_COEFR 0x4C +#define OV7725_FixGain 0x4D +#define OV7725_AREF1 0x4F +#define OV7725_AREF6 0x54 +#define OV7725_UFix 0x60 +#define OV7725_VFix 0x61 +#define OV7725_AWBb_blk 0x62 +#define OV7725_AWB_Ctrl0 0x63 +#define OV7725_DSP_Ctrl1 0x64 +#define OV7725_DSP_Ctrl2 0x65 +#define OV7725_DSP_Ctrl3 0x66 +#define OV7725_DSP_Ctrl4 0x67 +#define OV7725_AWB_bias 0x68 +#define OV7725_AWBCtrl1 0x69 +#define OV7725_AWBCtrl2 0x6A +#define OV7725_AWBCtrl3 0x6B +#define OV7725_AWBCtrl4 0x6C +#define OV7725_AWBCtrl5 0x6D +#define OV7725_AWBCtrl6 0x6E +#define OV7725_AWBCtrl7 0x6F +#define OV7725_AWBCtrl8 0x70 +#define OV7725_AWBCtrl9 0x71 +#define OV7725_AWBCtrl10 0x72 +#define OV7725_AWBCtrl11 0x73 +#define OV7725_AWBCtrl12 0x74 +#define OV7725_AWBCtrl13 0x75 +#define OV7725_AWBCtrl14 0x76 +#define OV7725_AWBCtrl15 0x77 +#define OV7725_AWBCtrl16 0x78 +#define OV7725_AWBCtrl17 0x79 +#define OV7725_AWBCtrl18 0x7A +#define OV7725_AWBCtrl19 0x7B +#define OV7725_AWBCtrl20 0x7C +#define OV7725_AWBCtrl21 0x7D +#define OV7725_GAM1 0x7E +#define OV7725_GAM2 0x7F +#define OV7725_GAM3 0x80 +#define OV7725_GAM4 0x81 +#define OV7725_GAM5 0x82 +#define OV7725_GAM6 0x83 +#define OV7725_GAM7 0x84 +#define OV7725_GAM8 0x85 +#define OV7725_GAM9 0x86 +#define OV7725_GAM10 0x87 +#define OV7725_GAM11 0x88 +#define OV7725_GAM12 0x89 +#define OV7725_GAM13 0x8A +#define OV7725_GAM14 0x8B +#define OV7725_GAM15 0x8C +#define OV7725_SLOP 0x8D +#define OV7725_DNSTh 0x8E +#define OV7725_EDGE0 0x8F +#define OV7725_EDGE1 0x90 +#define OV7725_DNSOff 0x91 +#define OV7725_EDGE2 0x92 +#define OV7725_EDGE3 0x93 +#define OV7725_MTX1 0x94 +#define OV7725_MTX2 0x95 +#define OV7725_MTX3 0x96 +#define OV7725_MTX4 0x97 +#define OV7725_MTX5 0x98 +#define OV7725_MTX6 0x99 +#define OV7725_MTX_Ctrl 0x9A +#define OV7725_BRIGHT 0x9B +#define OV7725_CNST 0x9C +#define OV7725_UVADJ0 0x9E +#define OV7725_UVADJ1 0x9F +#define OV7725_SCAL0 0xA0 +#define OV7725_SCAL1 0xA1 +#define OV7725_SCAL2 0xA2 +#define OV7725_SDE 0xA6 +#define OV7725_USAT 0xA7 +#define OV7725_VSAT 0xA8 +#define OV7725_HUECOS 0xA9 +#define OV7725_HUESIN 0xAA +#define OV7725_SIGN 0xAB +#define OV7725_DSPAuto 0xAC + + +#define OV7725_DEV_ADD 0x42>>1 + + +//ͷ +#define OV7725_W 160 //ͷͼ ò 80 160 240 320 +#define OV7725_H 120 //ͷͼ߶ ò 60 120 180 240 +#define OV7725_SIZE (OV7725_W * OV7725_H/8 ) //ͼռÿռС +#define OV7725_DMA_NUM (OV7725_SIZE) //һͼDMAɼ + + +//-------------------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------------------- +#define OV7725_VSYNC_PIN ERU_CH3_REQ6_P02_0 //ж ѡΧοERU_PIN_enumö ѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DATA_PIN P00_0 //D0 D0ΪP00_0 ôD1ʹõΪP00_1 + //òP00_0P02_0P15_0Ϊ + +#define OV7725_PCLK_PIN ERU_CH2_REQ14_P02_1 //ʱ ѡΧοERU_PIN_enumö 볡жѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ + //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 + + + +extern uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +extern uint8 image_dec[OV7725_H][OV7725_W]; //ͼѹ + +extern uint8 ov7725_finish_flag; //ͼɼɱ־λ + + +// +uint8 ov7725_init(void); +void ov7725_vsync(void); +void ov7725_dma(void); +void image_decompression(uint8 *data1,uint8 *data2); +void seekfree_sendimg_7725(UARTN_enum uartn); + + + +#endif + + + diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c index 095f9e3..5d167c9 100644 --- a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c @@ -68,6 +68,7 @@ void icm20602_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void icm20602_init(void) { + simiic_init(); systick_delay_ms(STM0, 10); //ϵʱ // diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c index 196fd57..f56a41a 100644 --- a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c @@ -50,7 +50,7 @@ uint8 IIC_num; // -static uint16 simiic_delay_time=100; //ICMȴӦΪ100 +static uint16 simiic_delay_time = SIMIIC_DELAY_TIME; //ICMȴӦΪ20 //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h index 293a02a..6a9c1e3 100644 --- a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h @@ -34,8 +34,12 @@ -#define SEEKFREE_SCL P13_0 //SCL ΪIO -#define SEEKFREE_SDA P13_1 //SDA ΪIO +#define SEEKFREE_SCL P02_3 //SCL ΪIO +#define SEEKFREE_SDA P02_2 //SDA ΪIO + + +#define SIMIIC_DELAY_TIME 20 + typedef enum IIC //DACģ { diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c index 0f0c23a..5deb7d3 100644 --- a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c @@ -65,6 +65,7 @@ void l3g4200d_self_check(void) //------------------------------------------------------------------------------------------------------------------- void l3g4200d_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); l3g4200d_self_check(); diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c index c200427..8a5eec4 100644 --- a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c @@ -68,6 +68,7 @@ void mma8451_self_check(void) //------------------------------------------------------------------------------------------------------------------- uint8 mma845x_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); mma8451_self_check(); diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c index 0317aa0..686550d 100644 --- a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c @@ -71,6 +71,7 @@ void mpu6050_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void mpu6050_init(void) { + simiic_init(); systick_delay_ms(STM0, 100); //ϵʱ mpu6050_self1_check(); diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c index 014b435..05f181f 100644 --- a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c @@ -38,7 +38,6 @@ #include "zf_gpio.h" #include "zf_eru.h" #include "zf_eru_dma.h" -#include "stdio.h" #include "SEEKFREE_MT9V03X.h" @@ -49,6 +48,8 @@ uint8 receive[3]; uint8 receive_num = 0; vuint8 uart_receive_flag; +uint8 link_list_num; + //Ҫõͷ int16 MT9V03X_CFG[CONFIG_FINISH][2]= { @@ -305,7 +306,7 @@ void mt9v03x_init(void) gpio_init((PIN_enum)(MT9V03X_DATA_PIN+i), GPI, 0, PULLUP); } - eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W); + link_list_num = eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W*MT9V03X_H); eru_init(MT9V03X_VSYNC_PIN, FALLING); //ʼжϣΪ½شж restoreInterrupts(interrupt_state); @@ -313,7 +314,6 @@ void mt9v03x_init(void) uint8 mt9v03x_finish_flag = 0; //һͼɼɱ־λ -uint8 now_col; //ǰڲɼ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03Xͷж // @param NULL @@ -324,16 +324,15 @@ uint8 now_col; // void mt9v03x_vsync(void) { CLEAR_GPIO_FLAG(MT9V03X_VSYNC_PIN); - now_col = 0; + if(!mt9v03x_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ { - DMA_SET_DESTINATION(MT9V03X_DMA_CH, (void *)&mt9v03x_image[0]); dma_start(MT9V03X_DMA_CH); } } - +uint8 mt9v03x_dma_int_num; //ǰDMAжϴ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03XͷDMAж // @param NULL @@ -344,16 +343,15 @@ void mt9v03x_vsync(void) void mt9v03x_dma(void) { CLEAR_DMA_FLAG(MT9V03X_DMA_CH); + mt9v03x_dma_int_num++; - now_col++; - - if(MT9V03X_H > now_col) - { - dma_start(MT9V03X_DMA_CH); - } - else + if(mt9v03x_dma_int_num >= link_list_num) { + //ɼ + mt9v03x_dma_int_num = 0; mt9v03x_finish_flag = 1;//һͼӲɼʼɼʱ3.8MS(50FPS188*120ֱ) + dma_stop(MT9V03X_DMA_CH); + } } diff --git a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h index a29edd2..0c8a785 100644 --- a/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h +++ b/Example/10-Interrupt_Priority_Set_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h @@ -63,9 +63,7 @@ //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ #define MT9V03X_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ - //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 - - + //ͷö typedef enum { diff --git a/Example/10-Interrupt_Priority_Set_Demo/USER/isr.c b/Example/10-Interrupt_Priority_Set_Demo/USER/isr.c index 15666f2..c6376b0 100644 --- a/Example/10-Interrupt_Priority_Set_Demo/USER/isr.c +++ b/Example/10-Interrupt_Priority_Set_Demo/USER/isr.c @@ -98,7 +98,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) if(GET_GPIO_FLAG(ERU_CH3_REQ6_P02_0))//ͨ3ж { CLEAR_GPIO_FLAG(ERU_CH3_REQ6_P02_0); - if(1 == camera_type)mt9v03x_vsync(); + if (1 == camera_type) mt9v03x_vsync(); + else if (3 == camera_type) ov7725_vsync(); } if(GET_GPIO_FLAG(ERU_CH7_REQ16_P15_1))//ͨ7ж @@ -113,7 +114,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) IFX_INTERRUPT(dma_ch5_isr, ERU_DMA_INT_SERVICE, ERU_DMA_INT_PRIO) { - if(1 == camera_type) mt9v03x_dma(); + if (1 == camera_type) mt9v03x_dma(); + else if (3 == camera_type) ov7725_dma(); } diff --git a/Example/11-Systick_Demo/Libraries/doc/version.txt b/Example/11-Systick_Demo/Libraries/doc/version.txt index b85cd50..a42bc58 100644 --- a/Example/11-Systick_Demo/Libraries/doc/version.txt +++ b/Example/11-Systick_Demo/Libraries/doc/version.txt @@ -1,9 +1,17 @@ V1.0.0 - ʼ汾 + ʼ汾 V1.0.1 ͷijжϽ޸ģжϱ־λΪ0Ųɼһͼ񣬱ַʳͻ ޸SPIʼеĴ˹̶SPI2ַ ޸STM޷ʹSTM1 - ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ \ No newline at end of file + ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ + +V1.0.2 + ޸ģIICĬʱʱΪ20 + ҪرעP20_2DzģֻĹ ע + ͷɼDMAΪlink䣬Դ󽵵DMAжϴ + ޸ĬϵIICŶ + 6050 ҪõIICģ飬ڳʼĬϵģIICʼ + С \ No newline at end of file diff --git a/Example/11-Systick_Demo/Libraries/seekfree_libraries/common/common.c b/Example/11-Systick_Demo/Libraries/seekfree_libraries/common/common.c index 0460d15..ac42b19 100644 --- a/Example/11-Systick_Demo/Libraries/seekfree_libraries/common/common.c +++ b/Example/11-Systick_Demo/Libraries/seekfree_libraries/common/common.c @@ -22,7 +22,7 @@ #include "SysSe/Bsp/Bsp.h" #include "common.h" -uint8 camera_type; +uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С diff --git a/Example/11-Systick_Demo/Libraries/seekfree_libraries/common/common.h b/Example/11-Systick_Demo/Libraries/seekfree_libraries/common/common.h index fe7ec63..13d03cd 100644 --- a/Example/11-Systick_Demo/Libraries/seekfree_libraries/common/common.h +++ b/Example/11-Systick_Demo/Libraries/seekfree_libraries/common/common.h @@ -111,7 +111,7 @@ typedef enum //ö #include -extern uint8 camera_type; +extern uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С void get_clk(void); diff --git a/Example/11-Systick_Demo/Libraries/seekfree_libraries/headfile.h b/Example/11-Systick_Demo/Libraries/seekfree_libraries/headfile.h index 0e8024f..e11bd83 100644 --- a/Example/11-Systick_Demo/Libraries/seekfree_libraries/headfile.h +++ b/Example/11-Systick_Demo/Libraries/seekfree_libraries/headfile.h @@ -62,6 +62,7 @@ #include "SEEKFREE_L3G4200D.h" #include "SEEKFREE_WIRELESS.h" #include "SEEKFREE_IPS200_PARALLEL8.h" +#include "SEEKFREE_7725.h" #endif diff --git a/Example/11-Systick_Demo/Libraries/seekfree_libraries/zf_eru_dma.c b/Example/11-Systick_Demo/Libraries/seekfree_libraries/zf_eru_dma.c index f7aab10..86c0158 100644 --- a/Example/11-Systick_Demo/Libraries/seekfree_libraries/zf_eru_dma.c +++ b/Example/11-Systick_Demo/Libraries/seekfree_libraries/zf_eru_dma.c @@ -21,9 +21,18 @@ #include "IfxDma_Dma.h" #include "IfxScuEru.h" #include "isr_config.h" +#include "zf_assert.h" #include "zf_eru_dma.h" +typedef struct +{ + Ifx_DMA_CH IFX_ALIGN(256) linked_list[8];//DMA + IfxDma_Dma_Channel channel; //DMAͨ +}DMA_LINK; + + +DMA_LINK dma_link_list; //------------------------------------------------------------------------------------------------------------------- // @brief erudmaʼ @@ -36,7 +45,7 @@ // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) { IfxDma_Dma_Channel dmaChn; //eruDMAͨ eruļeruȼΪͨ @@ -51,27 +60,85 @@ void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destinatio IfxDma_Dma_ChannelConfig cfg; IfxDma_Dma_initChannelConfig(&cfg, &dma); - cfg.transferCount = dma_count; + uint8 list_num, i; + uint16 single_channel_dma_count; + + ZF_ASSERT(!(dma_count%8));//Ϊ8ı + + + list_num = 1; + single_channel_dma_count = dma_count / list_num; + if(16384 < single_channel_dma_count) + { + while(TRUE) + { + single_channel_dma_count = dma_count / list_num; + if((single_channel_dma_count <= 16384) && !(dma_count % list_num)) + { + break; + } + list_num++; + if(list_num > 8) ZF_ASSERT(FALSE); + } + } + + + if(1 == list_num) + { + cfg.shadowControl = IfxDma_ChannelShadow_none; + cfg.operationMode = IfxDma_ChannelOperationMode_single; + cfg.shadowAddress = 0; + } + else + { + cfg.shadowControl = IfxDma_ChannelShadow_linkedList; + cfg.operationMode = IfxDma_ChannelOperationMode_continuous; + cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[1]); + } + cfg.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest; cfg.moveSize = IfxDma_ChannelMoveSize_8bit; + cfg.busPriority = IfxDma_ChannelBusPriority_high; - cfg.busPriority = IfxDma_ChannelBusPriority_high; - - cfg.sourceAddress = (unsigned)(source_addr); + cfg.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), source_addr); cfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_none; cfg.sourceCircularBufferEnabled = TRUE; - cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); cfg.destinationAddressIncrementStep = IfxDma_ChannelIncrementStep_1; - cfg.operationMode = IfxDma_ChannelOperationMode_single; - cfg.channelId = (IfxDma_ChannelId)dma_ch; - cfg.hardwareRequestEnabled = TRUE; - cfg.channelInterruptEnabled = TRUE; + cfg.channelId = (IfxDma_ChannelId)dma_ch; + cfg.hardwareRequestEnabled = FALSE; + cfg.channelInterruptEnabled = TRUE; cfg.channelInterruptPriority = ERU_DMA_INT_PRIO; cfg.channelInterruptTypeOfService = (IfxSrc_Tos)ERU_DMA_INT_SERVICE; + + + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); + + cfg.transferCount = single_channel_dma_count; + IfxDma_Dma_initChannel(&dmaChn, &cfg); + + if(1 < list_num) + { + i = 0; + while(i < list_num) + { + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr + single_channel_dma_count * i); + if(i == (list_num - 1)) cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[0]); + else cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[i+1]); + cfg.transferCount = single_channel_dma_count; + + IfxDma_Dma_initLinkedListEntry((void *)&dma_link_list.linked_list[i], &cfg); + i++; + } + } + + + IfxDma_Dma_getSrcPointer(&dma_link_list.channel)->B.CLRR = 1; + + return list_num; } diff --git a/Example/11-Systick_Demo/Libraries/seekfree_libraries/zf_eru_dma.h b/Example/11-Systick_Demo/Libraries/seekfree_libraries/zf_eru_dma.h index 50667ad..faef169 100644 --- a/Example/11-Systick_Demo/Libraries/seekfree_libraries/zf_eru_dma.h +++ b/Example/11-Systick_Demo/Libraries/seekfree_libraries/zf_eru_dma.h @@ -29,9 +29,9 @@ #define CLEAR_DMA_FLAG(dma_ch) IfxDma_clearChannelInterrupt(&MODULE_DMA, dma_ch); -#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)destination_addr) +#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr)) -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); void dma_stop(IfxDma_ChannelId dma_ch); void dma_start(IfxDma_ChannelId dma_ch); diff --git a/Example/11-Systick_Demo/Libraries/seekfree_libraries/zf_gpio.c b/Example/11-Systick_Demo/Libraries/seekfree_libraries/zf_gpio.c index 3c937cf..1d2466c 100644 --- a/Example/11-Systick_Demo/Libraries/seekfree_libraries/zf_gpio.c +++ b/Example/11-Systick_Demo/Libraries/seekfree_libraries/zf_gpio.c @@ -60,6 +60,7 @@ Ifx_P* get_port(PIN_enum pin) // @param pinmode ãòzf_gpio.hļGPIOMODE_enumöֵȷ // @return void // Sample usage: gpio_init(P00_0, GPO, 1, PUSHPULL);//P00_0ʼΪGPIOܡģʽߵƽ +// @note ҪرעP20_2DzģֻĹ //------------------------------------------------------------------------------------------------------------------- void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinmode) { diff --git a/Example/11-Systick_Demo/Libraries/seekfree_libraries/zf_gpio.h b/Example/11-Systick_Demo/Libraries/seekfree_libraries/zf_gpio.h index cfbd666..e3d144f 100644 --- a/Example/11-Systick_Demo/Libraries/seekfree_libraries/zf_gpio.h +++ b/Example/11-Systick_Demo/Libraries/seekfree_libraries/zf_gpio.h @@ -38,6 +38,15 @@ typedef enum // ö #define GET_PORT_IN_ADDR(pin) (uint8 *)(&IfxPort_getAddress((IfxPort_Index)(pin/32))->IN + pin%32/8) + + +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ + + + + //------------------------------------------------------ //ͨGPIO void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinconf); diff --git a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c new file mode 100644 index 0000000..806b8d9 --- /dev/null +++ b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c @@ -0,0 +1,262 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + +#include "IfxDma.h" +#include "IfxScuEru.h" +#include "zf_stm_systick.h" +#include "zf_gpio.h" +#include "zf_eru.h" +#include "zf_eru_dma.h" +#include "SEEKFREE_IIC.h" +#include "SEEKFREE_7725.h" + + + +IFX_ALIGN(4) uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +uint8 image_dec[OV7725_H][OV7725_W]; + +uint8 ov7725_idcode = 0; + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷڲĴʼ(ڲʹãû) +// @param NULL +// @return uint8 01ɹ +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_reg_init(void) +{ + simiic_delay_set(500); + simiic_write_reg ( OV7725_DEV_ADD, OV7725_COM7, 0x80 ); //λͷ + systick_delay_ms(STM0, 50); + ov7725_idcode = simiic_read_reg( OV7725_DEV_ADD, OV7725_VER ,SCCB); + if( ov7725_idcode != OV7725_ID ) return 0; //УͷID + + //IDȷ ȻüĴ + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM4 , 0xC1); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CLKRC , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM2 , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM3 , 0xD0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM7 , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM8 , 0xCE); //0xCE:رԶع 0xCFԶع + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSTART , 0x3F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSIZE , 0x50); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSTRT , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSIZE , 0x78); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HREF , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SCAL0 , 0x0A); + simiic_write_reg(OV7725_DEV_ADD, OV7725_AWB_Ctrl0 , 0xE0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSPAuto , 0xff); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl2 , 0x0C); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl3 , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl4 , 0x00); + + if(OV7725_W == 80) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x14); + else if(OV7725_W == 160) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x28); + else if(OV7725_W == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x3c); + else if(OV7725_W == 320) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x50); + + if(OV7725_H == 60) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x1E); + else if(OV7725_H == 120) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x3c); + else if(OV7725_H == 180) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x5a); + else if(OV7725_H == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x78); + + simiic_write_reg(OV7725_DEV_ADD, OV7725_REG28 , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCH , 0x10); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCL , 0x1F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM1 , 0x0c); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM2 , 0x16); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM3 , 0x2a); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM4 , 0x4e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM5 , 0x61); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM6 , 0x6f); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM7 , 0x7b); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM8 , 0x86); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM9 , 0x8e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM10 , 0x97); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM11 , 0xa4); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM12 , 0xaf); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM13 , 0xc5); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM14 , 0xd7); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM15 , 0xe8); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SLOP , 0x20); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_RADI , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEF , 0x13); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_XC , 0x08); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFB , 0x14); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFR , 0x17); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_CTR , 0x05); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDBase , 0x99); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDMStep , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SDE , 0x04); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BRIGHT , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CNST , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SIGN , 0x06); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ0 , 0x11); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ1 , 0x02); + + + simiic_delay_set(SIMIIC_DELAY_TIME);//޸ΪĬϵ20 + return 1; + + +} + + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷɼʼ(ڲʹãû) +// @param NULL +// @return void +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +void ov7725_port_init(void) +{ + uint8 i; + camera_type = 3;//ͷ + + //ͷɼʼ + //ʼ + for(i=0; i<8; i++) + { + gpio_init((PIN_enum)(OV7725_DATA_PIN+i), GPI, 0, PULLUP); + } + eru_dma_init(OV7725_DMA_CH, GET_PORT_IN_ADDR(OV7725_DATA_PIN), image_bin[0], OV7725_PCLK_PIN, FALLING, OV7725_DMA_NUM); + eru_init(OV7725_VSYNC_PIN, FALLING); //ʼжϣΪ½شж + +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷʼ(֮úжϺɲɼͼ) +// @param NULL +// @return 0 +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_init(void) +{ + simiic_init(); + ov7725_reg_init(); //ͷĴ + ov7725_port_init(); //ͷжżDMA + return 0; +} + + + + +uint8 ov7725_finish_flag = 0; +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбeruGPIOжϣжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_vsync(void) +{ + CLEAR_GPIO_FLAG(OV7725_VSYNC_PIN); + + if(!ov7725_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ + { + DMA_SET_DESTINATION(OV7725_DMA_CH, image_bin[0]); + dma_start(OV7725_DMA_CH); + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷDMAж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбdmaжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_dma(void) +{ + CLEAR_DMA_FLAG(OV7725_DMA_CH); + ov7725_finish_flag = 1; + dma_stop(OV7725_DMA_CH); +} + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷݽѹ +// @param *data1 Դַ +// @param *data2 Ŀĵַ +// @return void +// @since v1.0 +// Sample usage: Image_Decompression(da1,dat2[0]);//һάdat1ݽѹάdat2. +//------------------------------------------------------------------------------------------------------------------- +void image_decompression(uint8 *data1,uint8 *data2) +{ + uint8 temp[2] = {0,255}; + uint16 lenth = OV7725_SIZE; + uint8 i = 8; + + + while(lenth--) + { + i = 8; + while(i--) + { + *data2++ = temp[(*data1 >> i) & 0x01]; + } + data1++; + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷδѹͼλ鿴ͼ +// @param *imgaddr ѹͼݵַ +// @param *imgsize ͼС(ֱдOV7725_SIZE) +// @return void +// @since v1.0 +// Sample usage: øúǰȳʼuart2 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_sendimg_7725(UARTN_enum uartn) +{ + uart_putchar(uartn, 0x00);uart_putchar(uartn, 0xff);uart_putchar(uartn, 0x01);uart_putchar(uartn, 0x01);//ĸֽ + uart_putbuff(uartn, image_bin[0], OV7725_SIZE); //ٷͼ +} + + + + diff --git a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h new file mode 100644 index 0000000..e513250 --- /dev/null +++ b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h @@ -0,0 +1,243 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + + +#ifndef _SEEKFREE_7725_h +#define _SEEKFREE_7725_h + +#include "common.h" +#include "IfxDma_cfg.h" +#include "zf_uart.h" + + +//ͷID +#define OV7725_ID 0x21 + +//ͷĴ +#define OV7725_GAIN 0x00 +#define OV7725_BLUE 0x01 +#define OV7725_RED 0x02 +#define OV7725_GREEN 0x03 +#define OV7725_BAVG 0x05 +#define OV7725_GAVG 0x06 +#define OV7725_RAVG 0x07 +#define OV7725_AECH 0x08 +#define OV7725_COM2 0x09 +#define OV7725_PID 0x0A +#define OV7725_VER 0x0B +#define OV7725_COM3 0x0C +#define OV7725_COM4 0x0D +#define OV7725_COM5 0x0E +#define OV7725_COM6 0x0F +#define OV7725_AEC 0x10 +#define OV7725_CLKRC 0x11 +#define OV7725_COM7 0x12 +#define OV7725_COM8 0x13 +#define OV7725_COM9 0x14 +#define OV7725_COM10 0x15 +#define OV7725_REG16 0x16 +#define OV7725_HSTART 0x17 +#define OV7725_HSIZE 0x18 +#define OV7725_VSTRT 0x19 +#define OV7725_VSIZE 0x1A +#define OV7725_PSHFT 0x1B +#define OV7725_MIDH 0x1C +#define OV7725_MIDL 0x1D +#define OV7725_LAEC 0x1F +#define OV7725_COM11 0x20 +#define OV7725_BDBase 0x22 +#define OV7725_BDMStep 0x23 +#define OV7725_AEW 0x24 +#define OV7725_AEB 0x25 +#define OV7725_VPT 0x26 +#define OV7725_REG28 0x28 +#define OV7725_HOutSize 0x29 +#define OV7725_EXHCH 0x2A +#define OV7725_EXHCL 0x2B +#define OV7725_VOutSize 0x2C +#define OV7725_ADVFL 0x2D +#define OV7725_ADVFH 0x2E +#define OV7725_YAVE 0x2F +#define OV7725_LumHTh 0x30 +#define OV7725_LumLTh 0x31 +#define OV7725_HREF 0x32 +#define OV7725_DM_LNL 0x33 +#define OV7725_DM_LNH 0x34 +#define OV7725_ADoff_B 0x35 +#define OV7725_ADoff_R 0x36 +#define OV7725_ADoff_Gb 0x37 +#define OV7725_ADoff_Gr 0x38 +#define OV7725_Off_B 0x39 +#define OV7725_Off_R 0x3A +#define OV7725_Off_Gb 0x3B +#define OV7725_Off_Gr 0x3C +#define OV7725_COM12 0x3D +#define OV7725_COM13 0x3E +#define OV7725_COM14 0x3F +#define OV7725_COM16 0x41 +#define OV7725_TGT_B 0x42 +#define OV7725_TGT_R 0x43 +#define OV7725_TGT_Gb 0x44 +#define OV7725_TGT_Gr 0x45 +#define OV7725_LC_CTR 0x46 +#define OV7725_LC_XC 0x47 +#define OV7725_LC_YC 0x48 +#define OV7725_LC_COEF 0x49 +#define OV7725_LC_RADI 0x4A +#define OV7725_LC_COEFB 0x4B +#define OV7725_LC_COEFR 0x4C +#define OV7725_FixGain 0x4D +#define OV7725_AREF1 0x4F +#define OV7725_AREF6 0x54 +#define OV7725_UFix 0x60 +#define OV7725_VFix 0x61 +#define OV7725_AWBb_blk 0x62 +#define OV7725_AWB_Ctrl0 0x63 +#define OV7725_DSP_Ctrl1 0x64 +#define OV7725_DSP_Ctrl2 0x65 +#define OV7725_DSP_Ctrl3 0x66 +#define OV7725_DSP_Ctrl4 0x67 +#define OV7725_AWB_bias 0x68 +#define OV7725_AWBCtrl1 0x69 +#define OV7725_AWBCtrl2 0x6A +#define OV7725_AWBCtrl3 0x6B +#define OV7725_AWBCtrl4 0x6C +#define OV7725_AWBCtrl5 0x6D +#define OV7725_AWBCtrl6 0x6E +#define OV7725_AWBCtrl7 0x6F +#define OV7725_AWBCtrl8 0x70 +#define OV7725_AWBCtrl9 0x71 +#define OV7725_AWBCtrl10 0x72 +#define OV7725_AWBCtrl11 0x73 +#define OV7725_AWBCtrl12 0x74 +#define OV7725_AWBCtrl13 0x75 +#define OV7725_AWBCtrl14 0x76 +#define OV7725_AWBCtrl15 0x77 +#define OV7725_AWBCtrl16 0x78 +#define OV7725_AWBCtrl17 0x79 +#define OV7725_AWBCtrl18 0x7A +#define OV7725_AWBCtrl19 0x7B +#define OV7725_AWBCtrl20 0x7C +#define OV7725_AWBCtrl21 0x7D +#define OV7725_GAM1 0x7E +#define OV7725_GAM2 0x7F +#define OV7725_GAM3 0x80 +#define OV7725_GAM4 0x81 +#define OV7725_GAM5 0x82 +#define OV7725_GAM6 0x83 +#define OV7725_GAM7 0x84 +#define OV7725_GAM8 0x85 +#define OV7725_GAM9 0x86 +#define OV7725_GAM10 0x87 +#define OV7725_GAM11 0x88 +#define OV7725_GAM12 0x89 +#define OV7725_GAM13 0x8A +#define OV7725_GAM14 0x8B +#define OV7725_GAM15 0x8C +#define OV7725_SLOP 0x8D +#define OV7725_DNSTh 0x8E +#define OV7725_EDGE0 0x8F +#define OV7725_EDGE1 0x90 +#define OV7725_DNSOff 0x91 +#define OV7725_EDGE2 0x92 +#define OV7725_EDGE3 0x93 +#define OV7725_MTX1 0x94 +#define OV7725_MTX2 0x95 +#define OV7725_MTX3 0x96 +#define OV7725_MTX4 0x97 +#define OV7725_MTX5 0x98 +#define OV7725_MTX6 0x99 +#define OV7725_MTX_Ctrl 0x9A +#define OV7725_BRIGHT 0x9B +#define OV7725_CNST 0x9C +#define OV7725_UVADJ0 0x9E +#define OV7725_UVADJ1 0x9F +#define OV7725_SCAL0 0xA0 +#define OV7725_SCAL1 0xA1 +#define OV7725_SCAL2 0xA2 +#define OV7725_SDE 0xA6 +#define OV7725_USAT 0xA7 +#define OV7725_VSAT 0xA8 +#define OV7725_HUECOS 0xA9 +#define OV7725_HUESIN 0xAA +#define OV7725_SIGN 0xAB +#define OV7725_DSPAuto 0xAC + + +#define OV7725_DEV_ADD 0x42>>1 + + +//ͷ +#define OV7725_W 160 //ͷͼ ò 80 160 240 320 +#define OV7725_H 120 //ͷͼ߶ ò 60 120 180 240 +#define OV7725_SIZE (OV7725_W * OV7725_H/8 ) //ͼռÿռС +#define OV7725_DMA_NUM (OV7725_SIZE) //һͼDMAɼ + + +//-------------------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------------------- +#define OV7725_VSYNC_PIN ERU_CH3_REQ6_P02_0 //ж ѡΧοERU_PIN_enumö ѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DATA_PIN P00_0 //D0 D0ΪP00_0 ôD1ʹõΪP00_1 + //òP00_0P02_0P15_0Ϊ + +#define OV7725_PCLK_PIN ERU_CH2_REQ14_P02_1 //ʱ ѡΧοERU_PIN_enumö 볡жѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ + //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 + + + +extern uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +extern uint8 image_dec[OV7725_H][OV7725_W]; //ͼѹ + +extern uint8 ov7725_finish_flag; //ͼɼɱ־λ + + +// +uint8 ov7725_init(void); +void ov7725_vsync(void); +void ov7725_dma(void); +void image_decompression(uint8 *data1,uint8 *data2); +void seekfree_sendimg_7725(UARTN_enum uartn); + + + +#endif + + + diff --git a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c index 095f9e3..5d167c9 100644 --- a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c +++ b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c @@ -68,6 +68,7 @@ void icm20602_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void icm20602_init(void) { + simiic_init(); systick_delay_ms(STM0, 10); //ϵʱ // diff --git a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c index 196fd57..f56a41a 100644 --- a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c +++ b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c @@ -50,7 +50,7 @@ uint8 IIC_num; // -static uint16 simiic_delay_time=100; //ICMȴӦΪ100 +static uint16 simiic_delay_time = SIMIIC_DELAY_TIME; //ICMȴӦΪ20 //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h index 293a02a..6a9c1e3 100644 --- a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h +++ b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h @@ -34,8 +34,12 @@ -#define SEEKFREE_SCL P13_0 //SCL ΪIO -#define SEEKFREE_SDA P13_1 //SDA ΪIO +#define SEEKFREE_SCL P02_3 //SCL ΪIO +#define SEEKFREE_SDA P02_2 //SDA ΪIO + + +#define SIMIIC_DELAY_TIME 20 + typedef enum IIC //DACģ { diff --git a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c index 0f0c23a..5deb7d3 100644 --- a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c +++ b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c @@ -65,6 +65,7 @@ void l3g4200d_self_check(void) //------------------------------------------------------------------------------------------------------------------- void l3g4200d_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); l3g4200d_self_check(); diff --git a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c index c200427..8a5eec4 100644 --- a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c +++ b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c @@ -68,6 +68,7 @@ void mma8451_self_check(void) //------------------------------------------------------------------------------------------------------------------- uint8 mma845x_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); mma8451_self_check(); diff --git a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c index 0317aa0..686550d 100644 --- a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c +++ b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c @@ -71,6 +71,7 @@ void mpu6050_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void mpu6050_init(void) { + simiic_init(); systick_delay_ms(STM0, 100); //ϵʱ mpu6050_self1_check(); diff --git a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c index 014b435..05f181f 100644 --- a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c +++ b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c @@ -38,7 +38,6 @@ #include "zf_gpio.h" #include "zf_eru.h" #include "zf_eru_dma.h" -#include "stdio.h" #include "SEEKFREE_MT9V03X.h" @@ -49,6 +48,8 @@ uint8 receive[3]; uint8 receive_num = 0; vuint8 uart_receive_flag; +uint8 link_list_num; + //Ҫõͷ int16 MT9V03X_CFG[CONFIG_FINISH][2]= { @@ -305,7 +306,7 @@ void mt9v03x_init(void) gpio_init((PIN_enum)(MT9V03X_DATA_PIN+i), GPI, 0, PULLUP); } - eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W); + link_list_num = eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W*MT9V03X_H); eru_init(MT9V03X_VSYNC_PIN, FALLING); //ʼжϣΪ½شж restoreInterrupts(interrupt_state); @@ -313,7 +314,6 @@ void mt9v03x_init(void) uint8 mt9v03x_finish_flag = 0; //һͼɼɱ־λ -uint8 now_col; //ǰڲɼ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03Xͷж // @param NULL @@ -324,16 +324,15 @@ uint8 now_col; // void mt9v03x_vsync(void) { CLEAR_GPIO_FLAG(MT9V03X_VSYNC_PIN); - now_col = 0; + if(!mt9v03x_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ { - DMA_SET_DESTINATION(MT9V03X_DMA_CH, (void *)&mt9v03x_image[0]); dma_start(MT9V03X_DMA_CH); } } - +uint8 mt9v03x_dma_int_num; //ǰDMAжϴ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03XͷDMAж // @param NULL @@ -344,16 +343,15 @@ void mt9v03x_vsync(void) void mt9v03x_dma(void) { CLEAR_DMA_FLAG(MT9V03X_DMA_CH); + mt9v03x_dma_int_num++; - now_col++; - - if(MT9V03X_H > now_col) - { - dma_start(MT9V03X_DMA_CH); - } - else + if(mt9v03x_dma_int_num >= link_list_num) { + //ɼ + mt9v03x_dma_int_num = 0; mt9v03x_finish_flag = 1;//һͼӲɼʼɼʱ3.8MS(50FPS188*120ֱ) + dma_stop(MT9V03X_DMA_CH); + } } diff --git a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h index a29edd2..0c8a785 100644 --- a/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h +++ b/Example/11-Systick_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h @@ -63,9 +63,7 @@ //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ #define MT9V03X_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ - //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 - - + //ͷö typedef enum { diff --git a/Example/11-Systick_Demo/USER/isr.c b/Example/11-Systick_Demo/USER/isr.c index 15666f2..c6376b0 100644 --- a/Example/11-Systick_Demo/USER/isr.c +++ b/Example/11-Systick_Demo/USER/isr.c @@ -98,7 +98,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) if(GET_GPIO_FLAG(ERU_CH3_REQ6_P02_0))//ͨ3ж { CLEAR_GPIO_FLAG(ERU_CH3_REQ6_P02_0); - if(1 == camera_type)mt9v03x_vsync(); + if (1 == camera_type) mt9v03x_vsync(); + else if (3 == camera_type) ov7725_vsync(); } if(GET_GPIO_FLAG(ERU_CH7_REQ16_P15_1))//ͨ7ж @@ -113,7 +114,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) IFX_INTERRUPT(dma_ch5_isr, ERU_DMA_INT_SERVICE, ERU_DMA_INT_PRIO) { - if(1 == camera_type) mt9v03x_dma(); + if (1 == camera_type) mt9v03x_dma(); + else if (3 == camera_type) ov7725_dma(); } diff --git a/Example/12-Dual_Core_Demo/Libraries/doc/version.txt b/Example/12-Dual_Core_Demo/Libraries/doc/version.txt index b85cd50..a42bc58 100644 --- a/Example/12-Dual_Core_Demo/Libraries/doc/version.txt +++ b/Example/12-Dual_Core_Demo/Libraries/doc/version.txt @@ -1,9 +1,17 @@ V1.0.0 - ʼ汾 + ʼ汾 V1.0.1 ͷijжϽ޸ģжϱ־λΪ0Ųɼһͼ񣬱ַʳͻ ޸SPIʼеĴ˹̶SPI2ַ ޸STM޷ʹSTM1 - ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ \ No newline at end of file + ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ + +V1.0.2 + ޸ģIICĬʱʱΪ20 + ҪرעP20_2DzģֻĹ ע + ͷɼDMAΪlink䣬Դ󽵵DMAжϴ + ޸ĬϵIICŶ + 6050 ҪõIICģ飬ڳʼĬϵģIICʼ + С \ No newline at end of file diff --git a/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/common/common.c b/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/common/common.c index 0460d15..ac42b19 100644 --- a/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/common/common.c +++ b/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/common/common.c @@ -22,7 +22,7 @@ #include "SysSe/Bsp/Bsp.h" #include "common.h" -uint8 camera_type; +uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С diff --git a/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/common/common.h b/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/common/common.h index fe7ec63..13d03cd 100644 --- a/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/common/common.h +++ b/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/common/common.h @@ -111,7 +111,7 @@ typedef enum //ö #include -extern uint8 camera_type; +extern uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С void get_clk(void); diff --git a/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/headfile.h b/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/headfile.h index 0e8024f..e11bd83 100644 --- a/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/headfile.h +++ b/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/headfile.h @@ -62,6 +62,7 @@ #include "SEEKFREE_L3G4200D.h" #include "SEEKFREE_WIRELESS.h" #include "SEEKFREE_IPS200_PARALLEL8.h" +#include "SEEKFREE_7725.h" #endif diff --git a/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/zf_eru_dma.c b/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/zf_eru_dma.c index f7aab10..86c0158 100644 --- a/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/zf_eru_dma.c +++ b/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/zf_eru_dma.c @@ -21,9 +21,18 @@ #include "IfxDma_Dma.h" #include "IfxScuEru.h" #include "isr_config.h" +#include "zf_assert.h" #include "zf_eru_dma.h" +typedef struct +{ + Ifx_DMA_CH IFX_ALIGN(256) linked_list[8];//DMA + IfxDma_Dma_Channel channel; //DMAͨ +}DMA_LINK; + + +DMA_LINK dma_link_list; //------------------------------------------------------------------------------------------------------------------- // @brief erudmaʼ @@ -36,7 +45,7 @@ // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) { IfxDma_Dma_Channel dmaChn; //eruDMAͨ eruļeruȼΪͨ @@ -51,27 +60,85 @@ void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destinatio IfxDma_Dma_ChannelConfig cfg; IfxDma_Dma_initChannelConfig(&cfg, &dma); - cfg.transferCount = dma_count; + uint8 list_num, i; + uint16 single_channel_dma_count; + + ZF_ASSERT(!(dma_count%8));//Ϊ8ı + + + list_num = 1; + single_channel_dma_count = dma_count / list_num; + if(16384 < single_channel_dma_count) + { + while(TRUE) + { + single_channel_dma_count = dma_count / list_num; + if((single_channel_dma_count <= 16384) && !(dma_count % list_num)) + { + break; + } + list_num++; + if(list_num > 8) ZF_ASSERT(FALSE); + } + } + + + if(1 == list_num) + { + cfg.shadowControl = IfxDma_ChannelShadow_none; + cfg.operationMode = IfxDma_ChannelOperationMode_single; + cfg.shadowAddress = 0; + } + else + { + cfg.shadowControl = IfxDma_ChannelShadow_linkedList; + cfg.operationMode = IfxDma_ChannelOperationMode_continuous; + cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[1]); + } + cfg.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest; cfg.moveSize = IfxDma_ChannelMoveSize_8bit; + cfg.busPriority = IfxDma_ChannelBusPriority_high; - cfg.busPriority = IfxDma_ChannelBusPriority_high; - - cfg.sourceAddress = (unsigned)(source_addr); + cfg.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), source_addr); cfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_none; cfg.sourceCircularBufferEnabled = TRUE; - cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); cfg.destinationAddressIncrementStep = IfxDma_ChannelIncrementStep_1; - cfg.operationMode = IfxDma_ChannelOperationMode_single; - cfg.channelId = (IfxDma_ChannelId)dma_ch; - cfg.hardwareRequestEnabled = TRUE; - cfg.channelInterruptEnabled = TRUE; + cfg.channelId = (IfxDma_ChannelId)dma_ch; + cfg.hardwareRequestEnabled = FALSE; + cfg.channelInterruptEnabled = TRUE; cfg.channelInterruptPriority = ERU_DMA_INT_PRIO; cfg.channelInterruptTypeOfService = (IfxSrc_Tos)ERU_DMA_INT_SERVICE; + + + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); + + cfg.transferCount = single_channel_dma_count; + IfxDma_Dma_initChannel(&dmaChn, &cfg); + + if(1 < list_num) + { + i = 0; + while(i < list_num) + { + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr + single_channel_dma_count * i); + if(i == (list_num - 1)) cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[0]); + else cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[i+1]); + cfg.transferCount = single_channel_dma_count; + + IfxDma_Dma_initLinkedListEntry((void *)&dma_link_list.linked_list[i], &cfg); + i++; + } + } + + + IfxDma_Dma_getSrcPointer(&dma_link_list.channel)->B.CLRR = 1; + + return list_num; } diff --git a/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/zf_eru_dma.h b/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/zf_eru_dma.h index 50667ad..faef169 100644 --- a/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/zf_eru_dma.h +++ b/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/zf_eru_dma.h @@ -29,9 +29,9 @@ #define CLEAR_DMA_FLAG(dma_ch) IfxDma_clearChannelInterrupt(&MODULE_DMA, dma_ch); -#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)destination_addr) +#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr)) -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); void dma_stop(IfxDma_ChannelId dma_ch); void dma_start(IfxDma_ChannelId dma_ch); diff --git a/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/zf_gpio.c b/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/zf_gpio.c index 3c937cf..1d2466c 100644 --- a/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/zf_gpio.c +++ b/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/zf_gpio.c @@ -60,6 +60,7 @@ Ifx_P* get_port(PIN_enum pin) // @param pinmode ãòzf_gpio.hļGPIOMODE_enumöֵȷ // @return void // Sample usage: gpio_init(P00_0, GPO, 1, PUSHPULL);//P00_0ʼΪGPIOܡģʽߵƽ +// @note ҪرעP20_2DzģֻĹ //------------------------------------------------------------------------------------------------------------------- void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinmode) { diff --git a/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/zf_gpio.h b/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/zf_gpio.h index cfbd666..e3d144f 100644 --- a/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/zf_gpio.h +++ b/Example/12-Dual_Core_Demo/Libraries/seekfree_libraries/zf_gpio.h @@ -38,6 +38,15 @@ typedef enum // ö #define GET_PORT_IN_ADDR(pin) (uint8 *)(&IfxPort_getAddress((IfxPort_Index)(pin/32))->IN + pin%32/8) + + +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ + + + + //------------------------------------------------------ //ͨGPIO void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinconf); diff --git a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c new file mode 100644 index 0000000..806b8d9 --- /dev/null +++ b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c @@ -0,0 +1,262 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + +#include "IfxDma.h" +#include "IfxScuEru.h" +#include "zf_stm_systick.h" +#include "zf_gpio.h" +#include "zf_eru.h" +#include "zf_eru_dma.h" +#include "SEEKFREE_IIC.h" +#include "SEEKFREE_7725.h" + + + +IFX_ALIGN(4) uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +uint8 image_dec[OV7725_H][OV7725_W]; + +uint8 ov7725_idcode = 0; + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷڲĴʼ(ڲʹãû) +// @param NULL +// @return uint8 01ɹ +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_reg_init(void) +{ + simiic_delay_set(500); + simiic_write_reg ( OV7725_DEV_ADD, OV7725_COM7, 0x80 ); //λͷ + systick_delay_ms(STM0, 50); + ov7725_idcode = simiic_read_reg( OV7725_DEV_ADD, OV7725_VER ,SCCB); + if( ov7725_idcode != OV7725_ID ) return 0; //УͷID + + //IDȷ ȻüĴ + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM4 , 0xC1); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CLKRC , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM2 , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM3 , 0xD0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM7 , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM8 , 0xCE); //0xCE:رԶع 0xCFԶع + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSTART , 0x3F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSIZE , 0x50); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSTRT , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSIZE , 0x78); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HREF , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SCAL0 , 0x0A); + simiic_write_reg(OV7725_DEV_ADD, OV7725_AWB_Ctrl0 , 0xE0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSPAuto , 0xff); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl2 , 0x0C); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl3 , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl4 , 0x00); + + if(OV7725_W == 80) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x14); + else if(OV7725_W == 160) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x28); + else if(OV7725_W == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x3c); + else if(OV7725_W == 320) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x50); + + if(OV7725_H == 60) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x1E); + else if(OV7725_H == 120) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x3c); + else if(OV7725_H == 180) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x5a); + else if(OV7725_H == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x78); + + simiic_write_reg(OV7725_DEV_ADD, OV7725_REG28 , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCH , 0x10); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCL , 0x1F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM1 , 0x0c); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM2 , 0x16); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM3 , 0x2a); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM4 , 0x4e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM5 , 0x61); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM6 , 0x6f); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM7 , 0x7b); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM8 , 0x86); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM9 , 0x8e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM10 , 0x97); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM11 , 0xa4); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM12 , 0xaf); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM13 , 0xc5); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM14 , 0xd7); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM15 , 0xe8); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SLOP , 0x20); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_RADI , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEF , 0x13); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_XC , 0x08); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFB , 0x14); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFR , 0x17); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_CTR , 0x05); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDBase , 0x99); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDMStep , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SDE , 0x04); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BRIGHT , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CNST , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SIGN , 0x06); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ0 , 0x11); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ1 , 0x02); + + + simiic_delay_set(SIMIIC_DELAY_TIME);//޸ΪĬϵ20 + return 1; + + +} + + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷɼʼ(ڲʹãû) +// @param NULL +// @return void +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +void ov7725_port_init(void) +{ + uint8 i; + camera_type = 3;//ͷ + + //ͷɼʼ + //ʼ + for(i=0; i<8; i++) + { + gpio_init((PIN_enum)(OV7725_DATA_PIN+i), GPI, 0, PULLUP); + } + eru_dma_init(OV7725_DMA_CH, GET_PORT_IN_ADDR(OV7725_DATA_PIN), image_bin[0], OV7725_PCLK_PIN, FALLING, OV7725_DMA_NUM); + eru_init(OV7725_VSYNC_PIN, FALLING); //ʼжϣΪ½شж + +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷʼ(֮úжϺɲɼͼ) +// @param NULL +// @return 0 +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_init(void) +{ + simiic_init(); + ov7725_reg_init(); //ͷĴ + ov7725_port_init(); //ͷжżDMA + return 0; +} + + + + +uint8 ov7725_finish_flag = 0; +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбeruGPIOжϣжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_vsync(void) +{ + CLEAR_GPIO_FLAG(OV7725_VSYNC_PIN); + + if(!ov7725_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ + { + DMA_SET_DESTINATION(OV7725_DMA_CH, image_bin[0]); + dma_start(OV7725_DMA_CH); + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷDMAж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбdmaжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_dma(void) +{ + CLEAR_DMA_FLAG(OV7725_DMA_CH); + ov7725_finish_flag = 1; + dma_stop(OV7725_DMA_CH); +} + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷݽѹ +// @param *data1 Դַ +// @param *data2 Ŀĵַ +// @return void +// @since v1.0 +// Sample usage: Image_Decompression(da1,dat2[0]);//һάdat1ݽѹάdat2. +//------------------------------------------------------------------------------------------------------------------- +void image_decompression(uint8 *data1,uint8 *data2) +{ + uint8 temp[2] = {0,255}; + uint16 lenth = OV7725_SIZE; + uint8 i = 8; + + + while(lenth--) + { + i = 8; + while(i--) + { + *data2++ = temp[(*data1 >> i) & 0x01]; + } + data1++; + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷδѹͼλ鿴ͼ +// @param *imgaddr ѹͼݵַ +// @param *imgsize ͼС(ֱдOV7725_SIZE) +// @return void +// @since v1.0 +// Sample usage: øúǰȳʼuart2 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_sendimg_7725(UARTN_enum uartn) +{ + uart_putchar(uartn, 0x00);uart_putchar(uartn, 0xff);uart_putchar(uartn, 0x01);uart_putchar(uartn, 0x01);//ĸֽ + uart_putbuff(uartn, image_bin[0], OV7725_SIZE); //ٷͼ +} + + + + diff --git a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h new file mode 100644 index 0000000..e513250 --- /dev/null +++ b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h @@ -0,0 +1,243 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + + +#ifndef _SEEKFREE_7725_h +#define _SEEKFREE_7725_h + +#include "common.h" +#include "IfxDma_cfg.h" +#include "zf_uart.h" + + +//ͷID +#define OV7725_ID 0x21 + +//ͷĴ +#define OV7725_GAIN 0x00 +#define OV7725_BLUE 0x01 +#define OV7725_RED 0x02 +#define OV7725_GREEN 0x03 +#define OV7725_BAVG 0x05 +#define OV7725_GAVG 0x06 +#define OV7725_RAVG 0x07 +#define OV7725_AECH 0x08 +#define OV7725_COM2 0x09 +#define OV7725_PID 0x0A +#define OV7725_VER 0x0B +#define OV7725_COM3 0x0C +#define OV7725_COM4 0x0D +#define OV7725_COM5 0x0E +#define OV7725_COM6 0x0F +#define OV7725_AEC 0x10 +#define OV7725_CLKRC 0x11 +#define OV7725_COM7 0x12 +#define OV7725_COM8 0x13 +#define OV7725_COM9 0x14 +#define OV7725_COM10 0x15 +#define OV7725_REG16 0x16 +#define OV7725_HSTART 0x17 +#define OV7725_HSIZE 0x18 +#define OV7725_VSTRT 0x19 +#define OV7725_VSIZE 0x1A +#define OV7725_PSHFT 0x1B +#define OV7725_MIDH 0x1C +#define OV7725_MIDL 0x1D +#define OV7725_LAEC 0x1F +#define OV7725_COM11 0x20 +#define OV7725_BDBase 0x22 +#define OV7725_BDMStep 0x23 +#define OV7725_AEW 0x24 +#define OV7725_AEB 0x25 +#define OV7725_VPT 0x26 +#define OV7725_REG28 0x28 +#define OV7725_HOutSize 0x29 +#define OV7725_EXHCH 0x2A +#define OV7725_EXHCL 0x2B +#define OV7725_VOutSize 0x2C +#define OV7725_ADVFL 0x2D +#define OV7725_ADVFH 0x2E +#define OV7725_YAVE 0x2F +#define OV7725_LumHTh 0x30 +#define OV7725_LumLTh 0x31 +#define OV7725_HREF 0x32 +#define OV7725_DM_LNL 0x33 +#define OV7725_DM_LNH 0x34 +#define OV7725_ADoff_B 0x35 +#define OV7725_ADoff_R 0x36 +#define OV7725_ADoff_Gb 0x37 +#define OV7725_ADoff_Gr 0x38 +#define OV7725_Off_B 0x39 +#define OV7725_Off_R 0x3A +#define OV7725_Off_Gb 0x3B +#define OV7725_Off_Gr 0x3C +#define OV7725_COM12 0x3D +#define OV7725_COM13 0x3E +#define OV7725_COM14 0x3F +#define OV7725_COM16 0x41 +#define OV7725_TGT_B 0x42 +#define OV7725_TGT_R 0x43 +#define OV7725_TGT_Gb 0x44 +#define OV7725_TGT_Gr 0x45 +#define OV7725_LC_CTR 0x46 +#define OV7725_LC_XC 0x47 +#define OV7725_LC_YC 0x48 +#define OV7725_LC_COEF 0x49 +#define OV7725_LC_RADI 0x4A +#define OV7725_LC_COEFB 0x4B +#define OV7725_LC_COEFR 0x4C +#define OV7725_FixGain 0x4D +#define OV7725_AREF1 0x4F +#define OV7725_AREF6 0x54 +#define OV7725_UFix 0x60 +#define OV7725_VFix 0x61 +#define OV7725_AWBb_blk 0x62 +#define OV7725_AWB_Ctrl0 0x63 +#define OV7725_DSP_Ctrl1 0x64 +#define OV7725_DSP_Ctrl2 0x65 +#define OV7725_DSP_Ctrl3 0x66 +#define OV7725_DSP_Ctrl4 0x67 +#define OV7725_AWB_bias 0x68 +#define OV7725_AWBCtrl1 0x69 +#define OV7725_AWBCtrl2 0x6A +#define OV7725_AWBCtrl3 0x6B +#define OV7725_AWBCtrl4 0x6C +#define OV7725_AWBCtrl5 0x6D +#define OV7725_AWBCtrl6 0x6E +#define OV7725_AWBCtrl7 0x6F +#define OV7725_AWBCtrl8 0x70 +#define OV7725_AWBCtrl9 0x71 +#define OV7725_AWBCtrl10 0x72 +#define OV7725_AWBCtrl11 0x73 +#define OV7725_AWBCtrl12 0x74 +#define OV7725_AWBCtrl13 0x75 +#define OV7725_AWBCtrl14 0x76 +#define OV7725_AWBCtrl15 0x77 +#define OV7725_AWBCtrl16 0x78 +#define OV7725_AWBCtrl17 0x79 +#define OV7725_AWBCtrl18 0x7A +#define OV7725_AWBCtrl19 0x7B +#define OV7725_AWBCtrl20 0x7C +#define OV7725_AWBCtrl21 0x7D +#define OV7725_GAM1 0x7E +#define OV7725_GAM2 0x7F +#define OV7725_GAM3 0x80 +#define OV7725_GAM4 0x81 +#define OV7725_GAM5 0x82 +#define OV7725_GAM6 0x83 +#define OV7725_GAM7 0x84 +#define OV7725_GAM8 0x85 +#define OV7725_GAM9 0x86 +#define OV7725_GAM10 0x87 +#define OV7725_GAM11 0x88 +#define OV7725_GAM12 0x89 +#define OV7725_GAM13 0x8A +#define OV7725_GAM14 0x8B +#define OV7725_GAM15 0x8C +#define OV7725_SLOP 0x8D +#define OV7725_DNSTh 0x8E +#define OV7725_EDGE0 0x8F +#define OV7725_EDGE1 0x90 +#define OV7725_DNSOff 0x91 +#define OV7725_EDGE2 0x92 +#define OV7725_EDGE3 0x93 +#define OV7725_MTX1 0x94 +#define OV7725_MTX2 0x95 +#define OV7725_MTX3 0x96 +#define OV7725_MTX4 0x97 +#define OV7725_MTX5 0x98 +#define OV7725_MTX6 0x99 +#define OV7725_MTX_Ctrl 0x9A +#define OV7725_BRIGHT 0x9B +#define OV7725_CNST 0x9C +#define OV7725_UVADJ0 0x9E +#define OV7725_UVADJ1 0x9F +#define OV7725_SCAL0 0xA0 +#define OV7725_SCAL1 0xA1 +#define OV7725_SCAL2 0xA2 +#define OV7725_SDE 0xA6 +#define OV7725_USAT 0xA7 +#define OV7725_VSAT 0xA8 +#define OV7725_HUECOS 0xA9 +#define OV7725_HUESIN 0xAA +#define OV7725_SIGN 0xAB +#define OV7725_DSPAuto 0xAC + + +#define OV7725_DEV_ADD 0x42>>1 + + +//ͷ +#define OV7725_W 160 //ͷͼ ò 80 160 240 320 +#define OV7725_H 120 //ͷͼ߶ ò 60 120 180 240 +#define OV7725_SIZE (OV7725_W * OV7725_H/8 ) //ͼռÿռС +#define OV7725_DMA_NUM (OV7725_SIZE) //һͼDMAɼ + + +//-------------------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------------------- +#define OV7725_VSYNC_PIN ERU_CH3_REQ6_P02_0 //ж ѡΧοERU_PIN_enumö ѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DATA_PIN P00_0 //D0 D0ΪP00_0 ôD1ʹõΪP00_1 + //òP00_0P02_0P15_0Ϊ + +#define OV7725_PCLK_PIN ERU_CH2_REQ14_P02_1 //ʱ ѡΧοERU_PIN_enumö 볡жѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ + //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 + + + +extern uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +extern uint8 image_dec[OV7725_H][OV7725_W]; //ͼѹ + +extern uint8 ov7725_finish_flag; //ͼɼɱ־λ + + +// +uint8 ov7725_init(void); +void ov7725_vsync(void); +void ov7725_dma(void); +void image_decompression(uint8 *data1,uint8 *data2); +void seekfree_sendimg_7725(UARTN_enum uartn); + + + +#endif + + + diff --git a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c index 095f9e3..5d167c9 100644 --- a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c +++ b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c @@ -68,6 +68,7 @@ void icm20602_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void icm20602_init(void) { + simiic_init(); systick_delay_ms(STM0, 10); //ϵʱ // diff --git a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c index 196fd57..f56a41a 100644 --- a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c +++ b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c @@ -50,7 +50,7 @@ uint8 IIC_num; // -static uint16 simiic_delay_time=100; //ICMȴӦΪ100 +static uint16 simiic_delay_time = SIMIIC_DELAY_TIME; //ICMȴӦΪ20 //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h index 293a02a..6a9c1e3 100644 --- a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h +++ b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h @@ -34,8 +34,12 @@ -#define SEEKFREE_SCL P13_0 //SCL ΪIO -#define SEEKFREE_SDA P13_1 //SDA ΪIO +#define SEEKFREE_SCL P02_3 //SCL ΪIO +#define SEEKFREE_SDA P02_2 //SDA ΪIO + + +#define SIMIIC_DELAY_TIME 20 + typedef enum IIC //DACģ { diff --git a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c index 0f0c23a..5deb7d3 100644 --- a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c +++ b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c @@ -65,6 +65,7 @@ void l3g4200d_self_check(void) //------------------------------------------------------------------------------------------------------------------- void l3g4200d_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); l3g4200d_self_check(); diff --git a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c index c200427..8a5eec4 100644 --- a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c +++ b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c @@ -68,6 +68,7 @@ void mma8451_self_check(void) //------------------------------------------------------------------------------------------------------------------- uint8 mma845x_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); mma8451_self_check(); diff --git a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c index 0317aa0..686550d 100644 --- a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c +++ b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c @@ -71,6 +71,7 @@ void mpu6050_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void mpu6050_init(void) { + simiic_init(); systick_delay_ms(STM0, 100); //ϵʱ mpu6050_self1_check(); diff --git a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c index 014b435..05f181f 100644 --- a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c +++ b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c @@ -38,7 +38,6 @@ #include "zf_gpio.h" #include "zf_eru.h" #include "zf_eru_dma.h" -#include "stdio.h" #include "SEEKFREE_MT9V03X.h" @@ -49,6 +48,8 @@ uint8 receive[3]; uint8 receive_num = 0; vuint8 uart_receive_flag; +uint8 link_list_num; + //Ҫõͷ int16 MT9V03X_CFG[CONFIG_FINISH][2]= { @@ -305,7 +306,7 @@ void mt9v03x_init(void) gpio_init((PIN_enum)(MT9V03X_DATA_PIN+i), GPI, 0, PULLUP); } - eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W); + link_list_num = eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W*MT9V03X_H); eru_init(MT9V03X_VSYNC_PIN, FALLING); //ʼжϣΪ½شж restoreInterrupts(interrupt_state); @@ -313,7 +314,6 @@ void mt9v03x_init(void) uint8 mt9v03x_finish_flag = 0; //һͼɼɱ־λ -uint8 now_col; //ǰڲɼ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03Xͷж // @param NULL @@ -324,16 +324,15 @@ uint8 now_col; // void mt9v03x_vsync(void) { CLEAR_GPIO_FLAG(MT9V03X_VSYNC_PIN); - now_col = 0; + if(!mt9v03x_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ { - DMA_SET_DESTINATION(MT9V03X_DMA_CH, (void *)&mt9v03x_image[0]); dma_start(MT9V03X_DMA_CH); } } - +uint8 mt9v03x_dma_int_num; //ǰDMAжϴ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03XͷDMAж // @param NULL @@ -344,16 +343,15 @@ void mt9v03x_vsync(void) void mt9v03x_dma(void) { CLEAR_DMA_FLAG(MT9V03X_DMA_CH); + mt9v03x_dma_int_num++; - now_col++; - - if(MT9V03X_H > now_col) - { - dma_start(MT9V03X_DMA_CH); - } - else + if(mt9v03x_dma_int_num >= link_list_num) { + //ɼ + mt9v03x_dma_int_num = 0; mt9v03x_finish_flag = 1;//һͼӲɼʼɼʱ3.8MS(50FPS188*120ֱ) + dma_stop(MT9V03X_DMA_CH); + } } diff --git a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h index a29edd2..0c8a785 100644 --- a/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h +++ b/Example/12-Dual_Core_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h @@ -63,9 +63,7 @@ //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ #define MT9V03X_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ - //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 - - + //ͷö typedef enum { diff --git a/Example/12-Dual_Core_Demo/USER/isr.c b/Example/12-Dual_Core_Demo/USER/isr.c index 15666f2..c6376b0 100644 --- a/Example/12-Dual_Core_Demo/USER/isr.c +++ b/Example/12-Dual_Core_Demo/USER/isr.c @@ -98,7 +98,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) if(GET_GPIO_FLAG(ERU_CH3_REQ6_P02_0))//ͨ3ж { CLEAR_GPIO_FLAG(ERU_CH3_REQ6_P02_0); - if(1 == camera_type)mt9v03x_vsync(); + if (1 == camera_type) mt9v03x_vsync(); + else if (3 == camera_type) ov7725_vsync(); } if(GET_GPIO_FLAG(ERU_CH7_REQ16_P15_1))//ͨ7ж @@ -113,7 +114,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) IFX_INTERRUPT(dma_ch5_isr, ERU_DMA_INT_SERVICE, ERU_DMA_INT_PRIO) { - if(1 == camera_type) mt9v03x_dma(); + if (1 == camera_type) mt9v03x_dma(); + else if (3 == camera_type) ov7725_dma(); } diff --git a/Example/2-LED_Blink_Demo/Libraries/doc/version.txt b/Example/2-LED_Blink_Demo/Libraries/doc/version.txt index b85cd50..a42bc58 100644 --- a/Example/2-LED_Blink_Demo/Libraries/doc/version.txt +++ b/Example/2-LED_Blink_Demo/Libraries/doc/version.txt @@ -1,9 +1,17 @@ V1.0.0 - ʼ汾 + ʼ汾 V1.0.1 ͷijжϽ޸ģжϱ־λΪ0Ųɼһͼ񣬱ַʳͻ ޸SPIʼеĴ˹̶SPI2ַ ޸STM޷ʹSTM1 - ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ \ No newline at end of file + ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ + +V1.0.2 + ޸ģIICĬʱʱΪ20 + ҪرעP20_2DzģֻĹ ע + ͷɼDMAΪlink䣬Դ󽵵DMAжϴ + ޸ĬϵIICŶ + 6050 ҪõIICģ飬ڳʼĬϵģIICʼ + С \ No newline at end of file diff --git a/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/common/common.c b/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/common/common.c index 0460d15..ac42b19 100644 --- a/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/common/common.c +++ b/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/common/common.c @@ -22,7 +22,7 @@ #include "SysSe/Bsp/Bsp.h" #include "common.h" -uint8 camera_type; +uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С diff --git a/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/common/common.h b/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/common/common.h index fe7ec63..13d03cd 100644 --- a/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/common/common.h +++ b/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/common/common.h @@ -111,7 +111,7 @@ typedef enum //ö #include -extern uint8 camera_type; +extern uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С void get_clk(void); diff --git a/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/headfile.h b/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/headfile.h index 0e8024f..e11bd83 100644 --- a/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/headfile.h +++ b/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/headfile.h @@ -62,6 +62,7 @@ #include "SEEKFREE_L3G4200D.h" #include "SEEKFREE_WIRELESS.h" #include "SEEKFREE_IPS200_PARALLEL8.h" +#include "SEEKFREE_7725.h" #endif diff --git a/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/zf_eru_dma.c b/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/zf_eru_dma.c index f7aab10..86c0158 100644 --- a/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/zf_eru_dma.c +++ b/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/zf_eru_dma.c @@ -21,9 +21,18 @@ #include "IfxDma_Dma.h" #include "IfxScuEru.h" #include "isr_config.h" +#include "zf_assert.h" #include "zf_eru_dma.h" +typedef struct +{ + Ifx_DMA_CH IFX_ALIGN(256) linked_list[8];//DMA + IfxDma_Dma_Channel channel; //DMAͨ +}DMA_LINK; + + +DMA_LINK dma_link_list; //------------------------------------------------------------------------------------------------------------------- // @brief erudmaʼ @@ -36,7 +45,7 @@ // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) { IfxDma_Dma_Channel dmaChn; //eruDMAͨ eruļeruȼΪͨ @@ -51,27 +60,85 @@ void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destinatio IfxDma_Dma_ChannelConfig cfg; IfxDma_Dma_initChannelConfig(&cfg, &dma); - cfg.transferCount = dma_count; + uint8 list_num, i; + uint16 single_channel_dma_count; + + ZF_ASSERT(!(dma_count%8));//Ϊ8ı + + + list_num = 1; + single_channel_dma_count = dma_count / list_num; + if(16384 < single_channel_dma_count) + { + while(TRUE) + { + single_channel_dma_count = dma_count / list_num; + if((single_channel_dma_count <= 16384) && !(dma_count % list_num)) + { + break; + } + list_num++; + if(list_num > 8) ZF_ASSERT(FALSE); + } + } + + + if(1 == list_num) + { + cfg.shadowControl = IfxDma_ChannelShadow_none; + cfg.operationMode = IfxDma_ChannelOperationMode_single; + cfg.shadowAddress = 0; + } + else + { + cfg.shadowControl = IfxDma_ChannelShadow_linkedList; + cfg.operationMode = IfxDma_ChannelOperationMode_continuous; + cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[1]); + } + cfg.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest; cfg.moveSize = IfxDma_ChannelMoveSize_8bit; + cfg.busPriority = IfxDma_ChannelBusPriority_high; - cfg.busPriority = IfxDma_ChannelBusPriority_high; - - cfg.sourceAddress = (unsigned)(source_addr); + cfg.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), source_addr); cfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_none; cfg.sourceCircularBufferEnabled = TRUE; - cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); cfg.destinationAddressIncrementStep = IfxDma_ChannelIncrementStep_1; - cfg.operationMode = IfxDma_ChannelOperationMode_single; - cfg.channelId = (IfxDma_ChannelId)dma_ch; - cfg.hardwareRequestEnabled = TRUE; - cfg.channelInterruptEnabled = TRUE; + cfg.channelId = (IfxDma_ChannelId)dma_ch; + cfg.hardwareRequestEnabled = FALSE; + cfg.channelInterruptEnabled = TRUE; cfg.channelInterruptPriority = ERU_DMA_INT_PRIO; cfg.channelInterruptTypeOfService = (IfxSrc_Tos)ERU_DMA_INT_SERVICE; + + + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); + + cfg.transferCount = single_channel_dma_count; + IfxDma_Dma_initChannel(&dmaChn, &cfg); + + if(1 < list_num) + { + i = 0; + while(i < list_num) + { + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr + single_channel_dma_count * i); + if(i == (list_num - 1)) cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[0]); + else cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[i+1]); + cfg.transferCount = single_channel_dma_count; + + IfxDma_Dma_initLinkedListEntry((void *)&dma_link_list.linked_list[i], &cfg); + i++; + } + } + + + IfxDma_Dma_getSrcPointer(&dma_link_list.channel)->B.CLRR = 1; + + return list_num; } diff --git a/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/zf_eru_dma.h b/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/zf_eru_dma.h index 50667ad..faef169 100644 --- a/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/zf_eru_dma.h +++ b/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/zf_eru_dma.h @@ -29,9 +29,9 @@ #define CLEAR_DMA_FLAG(dma_ch) IfxDma_clearChannelInterrupt(&MODULE_DMA, dma_ch); -#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)destination_addr) +#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr)) -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); void dma_stop(IfxDma_ChannelId dma_ch); void dma_start(IfxDma_ChannelId dma_ch); diff --git a/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/zf_gpio.c b/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/zf_gpio.c index 3c937cf..1d2466c 100644 --- a/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/zf_gpio.c +++ b/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/zf_gpio.c @@ -60,6 +60,7 @@ Ifx_P* get_port(PIN_enum pin) // @param pinmode ãòzf_gpio.hļGPIOMODE_enumöֵȷ // @return void // Sample usage: gpio_init(P00_0, GPO, 1, PUSHPULL);//P00_0ʼΪGPIOܡģʽߵƽ +// @note ҪرעP20_2DzģֻĹ //------------------------------------------------------------------------------------------------------------------- void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinmode) { diff --git a/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/zf_gpio.h b/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/zf_gpio.h index cfbd666..e3d144f 100644 --- a/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/zf_gpio.h +++ b/Example/2-LED_Blink_Demo/Libraries/seekfree_libraries/zf_gpio.h @@ -38,6 +38,15 @@ typedef enum // ö #define GET_PORT_IN_ADDR(pin) (uint8 *)(&IfxPort_getAddress((IfxPort_Index)(pin/32))->IN + pin%32/8) + + +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ + + + + //------------------------------------------------------ //ͨGPIO void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinconf); diff --git a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c new file mode 100644 index 0000000..806b8d9 --- /dev/null +++ b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c @@ -0,0 +1,262 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + +#include "IfxDma.h" +#include "IfxScuEru.h" +#include "zf_stm_systick.h" +#include "zf_gpio.h" +#include "zf_eru.h" +#include "zf_eru_dma.h" +#include "SEEKFREE_IIC.h" +#include "SEEKFREE_7725.h" + + + +IFX_ALIGN(4) uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +uint8 image_dec[OV7725_H][OV7725_W]; + +uint8 ov7725_idcode = 0; + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷڲĴʼ(ڲʹãû) +// @param NULL +// @return uint8 01ɹ +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_reg_init(void) +{ + simiic_delay_set(500); + simiic_write_reg ( OV7725_DEV_ADD, OV7725_COM7, 0x80 ); //λͷ + systick_delay_ms(STM0, 50); + ov7725_idcode = simiic_read_reg( OV7725_DEV_ADD, OV7725_VER ,SCCB); + if( ov7725_idcode != OV7725_ID ) return 0; //УͷID + + //IDȷ ȻüĴ + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM4 , 0xC1); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CLKRC , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM2 , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM3 , 0xD0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM7 , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM8 , 0xCE); //0xCE:رԶع 0xCFԶع + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSTART , 0x3F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSIZE , 0x50); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSTRT , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSIZE , 0x78); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HREF , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SCAL0 , 0x0A); + simiic_write_reg(OV7725_DEV_ADD, OV7725_AWB_Ctrl0 , 0xE0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSPAuto , 0xff); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl2 , 0x0C); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl3 , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl4 , 0x00); + + if(OV7725_W == 80) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x14); + else if(OV7725_W == 160) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x28); + else if(OV7725_W == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x3c); + else if(OV7725_W == 320) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x50); + + if(OV7725_H == 60) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x1E); + else if(OV7725_H == 120) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x3c); + else if(OV7725_H == 180) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x5a); + else if(OV7725_H == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x78); + + simiic_write_reg(OV7725_DEV_ADD, OV7725_REG28 , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCH , 0x10); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCL , 0x1F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM1 , 0x0c); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM2 , 0x16); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM3 , 0x2a); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM4 , 0x4e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM5 , 0x61); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM6 , 0x6f); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM7 , 0x7b); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM8 , 0x86); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM9 , 0x8e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM10 , 0x97); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM11 , 0xa4); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM12 , 0xaf); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM13 , 0xc5); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM14 , 0xd7); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM15 , 0xe8); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SLOP , 0x20); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_RADI , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEF , 0x13); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_XC , 0x08); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFB , 0x14); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFR , 0x17); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_CTR , 0x05); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDBase , 0x99); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDMStep , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SDE , 0x04); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BRIGHT , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CNST , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SIGN , 0x06); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ0 , 0x11); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ1 , 0x02); + + + simiic_delay_set(SIMIIC_DELAY_TIME);//޸ΪĬϵ20 + return 1; + + +} + + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷɼʼ(ڲʹãû) +// @param NULL +// @return void +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +void ov7725_port_init(void) +{ + uint8 i; + camera_type = 3;//ͷ + + //ͷɼʼ + //ʼ + for(i=0; i<8; i++) + { + gpio_init((PIN_enum)(OV7725_DATA_PIN+i), GPI, 0, PULLUP); + } + eru_dma_init(OV7725_DMA_CH, GET_PORT_IN_ADDR(OV7725_DATA_PIN), image_bin[0], OV7725_PCLK_PIN, FALLING, OV7725_DMA_NUM); + eru_init(OV7725_VSYNC_PIN, FALLING); //ʼжϣΪ½شж + +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷʼ(֮úжϺɲɼͼ) +// @param NULL +// @return 0 +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_init(void) +{ + simiic_init(); + ov7725_reg_init(); //ͷĴ + ov7725_port_init(); //ͷжżDMA + return 0; +} + + + + +uint8 ov7725_finish_flag = 0; +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбeruGPIOжϣжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_vsync(void) +{ + CLEAR_GPIO_FLAG(OV7725_VSYNC_PIN); + + if(!ov7725_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ + { + DMA_SET_DESTINATION(OV7725_DMA_CH, image_bin[0]); + dma_start(OV7725_DMA_CH); + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷDMAж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбdmaжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_dma(void) +{ + CLEAR_DMA_FLAG(OV7725_DMA_CH); + ov7725_finish_flag = 1; + dma_stop(OV7725_DMA_CH); +} + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷݽѹ +// @param *data1 Դַ +// @param *data2 Ŀĵַ +// @return void +// @since v1.0 +// Sample usage: Image_Decompression(da1,dat2[0]);//һάdat1ݽѹάdat2. +//------------------------------------------------------------------------------------------------------------------- +void image_decompression(uint8 *data1,uint8 *data2) +{ + uint8 temp[2] = {0,255}; + uint16 lenth = OV7725_SIZE; + uint8 i = 8; + + + while(lenth--) + { + i = 8; + while(i--) + { + *data2++ = temp[(*data1 >> i) & 0x01]; + } + data1++; + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷδѹͼλ鿴ͼ +// @param *imgaddr ѹͼݵַ +// @param *imgsize ͼС(ֱдOV7725_SIZE) +// @return void +// @since v1.0 +// Sample usage: øúǰȳʼuart2 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_sendimg_7725(UARTN_enum uartn) +{ + uart_putchar(uartn, 0x00);uart_putchar(uartn, 0xff);uart_putchar(uartn, 0x01);uart_putchar(uartn, 0x01);//ĸֽ + uart_putbuff(uartn, image_bin[0], OV7725_SIZE); //ٷͼ +} + + + + diff --git a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h new file mode 100644 index 0000000..e513250 --- /dev/null +++ b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h @@ -0,0 +1,243 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + + +#ifndef _SEEKFREE_7725_h +#define _SEEKFREE_7725_h + +#include "common.h" +#include "IfxDma_cfg.h" +#include "zf_uart.h" + + +//ͷID +#define OV7725_ID 0x21 + +//ͷĴ +#define OV7725_GAIN 0x00 +#define OV7725_BLUE 0x01 +#define OV7725_RED 0x02 +#define OV7725_GREEN 0x03 +#define OV7725_BAVG 0x05 +#define OV7725_GAVG 0x06 +#define OV7725_RAVG 0x07 +#define OV7725_AECH 0x08 +#define OV7725_COM2 0x09 +#define OV7725_PID 0x0A +#define OV7725_VER 0x0B +#define OV7725_COM3 0x0C +#define OV7725_COM4 0x0D +#define OV7725_COM5 0x0E +#define OV7725_COM6 0x0F +#define OV7725_AEC 0x10 +#define OV7725_CLKRC 0x11 +#define OV7725_COM7 0x12 +#define OV7725_COM8 0x13 +#define OV7725_COM9 0x14 +#define OV7725_COM10 0x15 +#define OV7725_REG16 0x16 +#define OV7725_HSTART 0x17 +#define OV7725_HSIZE 0x18 +#define OV7725_VSTRT 0x19 +#define OV7725_VSIZE 0x1A +#define OV7725_PSHFT 0x1B +#define OV7725_MIDH 0x1C +#define OV7725_MIDL 0x1D +#define OV7725_LAEC 0x1F +#define OV7725_COM11 0x20 +#define OV7725_BDBase 0x22 +#define OV7725_BDMStep 0x23 +#define OV7725_AEW 0x24 +#define OV7725_AEB 0x25 +#define OV7725_VPT 0x26 +#define OV7725_REG28 0x28 +#define OV7725_HOutSize 0x29 +#define OV7725_EXHCH 0x2A +#define OV7725_EXHCL 0x2B +#define OV7725_VOutSize 0x2C +#define OV7725_ADVFL 0x2D +#define OV7725_ADVFH 0x2E +#define OV7725_YAVE 0x2F +#define OV7725_LumHTh 0x30 +#define OV7725_LumLTh 0x31 +#define OV7725_HREF 0x32 +#define OV7725_DM_LNL 0x33 +#define OV7725_DM_LNH 0x34 +#define OV7725_ADoff_B 0x35 +#define OV7725_ADoff_R 0x36 +#define OV7725_ADoff_Gb 0x37 +#define OV7725_ADoff_Gr 0x38 +#define OV7725_Off_B 0x39 +#define OV7725_Off_R 0x3A +#define OV7725_Off_Gb 0x3B +#define OV7725_Off_Gr 0x3C +#define OV7725_COM12 0x3D +#define OV7725_COM13 0x3E +#define OV7725_COM14 0x3F +#define OV7725_COM16 0x41 +#define OV7725_TGT_B 0x42 +#define OV7725_TGT_R 0x43 +#define OV7725_TGT_Gb 0x44 +#define OV7725_TGT_Gr 0x45 +#define OV7725_LC_CTR 0x46 +#define OV7725_LC_XC 0x47 +#define OV7725_LC_YC 0x48 +#define OV7725_LC_COEF 0x49 +#define OV7725_LC_RADI 0x4A +#define OV7725_LC_COEFB 0x4B +#define OV7725_LC_COEFR 0x4C +#define OV7725_FixGain 0x4D +#define OV7725_AREF1 0x4F +#define OV7725_AREF6 0x54 +#define OV7725_UFix 0x60 +#define OV7725_VFix 0x61 +#define OV7725_AWBb_blk 0x62 +#define OV7725_AWB_Ctrl0 0x63 +#define OV7725_DSP_Ctrl1 0x64 +#define OV7725_DSP_Ctrl2 0x65 +#define OV7725_DSP_Ctrl3 0x66 +#define OV7725_DSP_Ctrl4 0x67 +#define OV7725_AWB_bias 0x68 +#define OV7725_AWBCtrl1 0x69 +#define OV7725_AWBCtrl2 0x6A +#define OV7725_AWBCtrl3 0x6B +#define OV7725_AWBCtrl4 0x6C +#define OV7725_AWBCtrl5 0x6D +#define OV7725_AWBCtrl6 0x6E +#define OV7725_AWBCtrl7 0x6F +#define OV7725_AWBCtrl8 0x70 +#define OV7725_AWBCtrl9 0x71 +#define OV7725_AWBCtrl10 0x72 +#define OV7725_AWBCtrl11 0x73 +#define OV7725_AWBCtrl12 0x74 +#define OV7725_AWBCtrl13 0x75 +#define OV7725_AWBCtrl14 0x76 +#define OV7725_AWBCtrl15 0x77 +#define OV7725_AWBCtrl16 0x78 +#define OV7725_AWBCtrl17 0x79 +#define OV7725_AWBCtrl18 0x7A +#define OV7725_AWBCtrl19 0x7B +#define OV7725_AWBCtrl20 0x7C +#define OV7725_AWBCtrl21 0x7D +#define OV7725_GAM1 0x7E +#define OV7725_GAM2 0x7F +#define OV7725_GAM3 0x80 +#define OV7725_GAM4 0x81 +#define OV7725_GAM5 0x82 +#define OV7725_GAM6 0x83 +#define OV7725_GAM7 0x84 +#define OV7725_GAM8 0x85 +#define OV7725_GAM9 0x86 +#define OV7725_GAM10 0x87 +#define OV7725_GAM11 0x88 +#define OV7725_GAM12 0x89 +#define OV7725_GAM13 0x8A +#define OV7725_GAM14 0x8B +#define OV7725_GAM15 0x8C +#define OV7725_SLOP 0x8D +#define OV7725_DNSTh 0x8E +#define OV7725_EDGE0 0x8F +#define OV7725_EDGE1 0x90 +#define OV7725_DNSOff 0x91 +#define OV7725_EDGE2 0x92 +#define OV7725_EDGE3 0x93 +#define OV7725_MTX1 0x94 +#define OV7725_MTX2 0x95 +#define OV7725_MTX3 0x96 +#define OV7725_MTX4 0x97 +#define OV7725_MTX5 0x98 +#define OV7725_MTX6 0x99 +#define OV7725_MTX_Ctrl 0x9A +#define OV7725_BRIGHT 0x9B +#define OV7725_CNST 0x9C +#define OV7725_UVADJ0 0x9E +#define OV7725_UVADJ1 0x9F +#define OV7725_SCAL0 0xA0 +#define OV7725_SCAL1 0xA1 +#define OV7725_SCAL2 0xA2 +#define OV7725_SDE 0xA6 +#define OV7725_USAT 0xA7 +#define OV7725_VSAT 0xA8 +#define OV7725_HUECOS 0xA9 +#define OV7725_HUESIN 0xAA +#define OV7725_SIGN 0xAB +#define OV7725_DSPAuto 0xAC + + +#define OV7725_DEV_ADD 0x42>>1 + + +//ͷ +#define OV7725_W 160 //ͷͼ ò 80 160 240 320 +#define OV7725_H 120 //ͷͼ߶ ò 60 120 180 240 +#define OV7725_SIZE (OV7725_W * OV7725_H/8 ) //ͼռÿռС +#define OV7725_DMA_NUM (OV7725_SIZE) //һͼDMAɼ + + +//-------------------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------------------- +#define OV7725_VSYNC_PIN ERU_CH3_REQ6_P02_0 //ж ѡΧοERU_PIN_enumö ѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DATA_PIN P00_0 //D0 D0ΪP00_0 ôD1ʹõΪP00_1 + //òP00_0P02_0P15_0Ϊ + +#define OV7725_PCLK_PIN ERU_CH2_REQ14_P02_1 //ʱ ѡΧοERU_PIN_enumö 볡жѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ + //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 + + + +extern uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +extern uint8 image_dec[OV7725_H][OV7725_W]; //ͼѹ + +extern uint8 ov7725_finish_flag; //ͼɼɱ־λ + + +// +uint8 ov7725_init(void); +void ov7725_vsync(void); +void ov7725_dma(void); +void image_decompression(uint8 *data1,uint8 *data2); +void seekfree_sendimg_7725(UARTN_enum uartn); + + + +#endif + + + diff --git a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c index 095f9e3..5d167c9 100644 --- a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c +++ b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c @@ -68,6 +68,7 @@ void icm20602_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void icm20602_init(void) { + simiic_init(); systick_delay_ms(STM0, 10); //ϵʱ // diff --git a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c index 196fd57..f56a41a 100644 --- a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c +++ b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c @@ -50,7 +50,7 @@ uint8 IIC_num; // -static uint16 simiic_delay_time=100; //ICMȴӦΪ100 +static uint16 simiic_delay_time = SIMIIC_DELAY_TIME; //ICMȴӦΪ20 //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h index 293a02a..6a9c1e3 100644 --- a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h +++ b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h @@ -34,8 +34,12 @@ -#define SEEKFREE_SCL P13_0 //SCL ΪIO -#define SEEKFREE_SDA P13_1 //SDA ΪIO +#define SEEKFREE_SCL P02_3 //SCL ΪIO +#define SEEKFREE_SDA P02_2 //SDA ΪIO + + +#define SIMIIC_DELAY_TIME 20 + typedef enum IIC //DACģ { diff --git a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c index 0f0c23a..5deb7d3 100644 --- a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c +++ b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c @@ -65,6 +65,7 @@ void l3g4200d_self_check(void) //------------------------------------------------------------------------------------------------------------------- void l3g4200d_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); l3g4200d_self_check(); diff --git a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c index c200427..8a5eec4 100644 --- a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c +++ b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c @@ -68,6 +68,7 @@ void mma8451_self_check(void) //------------------------------------------------------------------------------------------------------------------- uint8 mma845x_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); mma8451_self_check(); diff --git a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c index 0317aa0..686550d 100644 --- a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c +++ b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c @@ -71,6 +71,7 @@ void mpu6050_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void mpu6050_init(void) { + simiic_init(); systick_delay_ms(STM0, 100); //ϵʱ mpu6050_self1_check(); diff --git a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c index 014b435..05f181f 100644 --- a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c +++ b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c @@ -38,7 +38,6 @@ #include "zf_gpio.h" #include "zf_eru.h" #include "zf_eru_dma.h" -#include "stdio.h" #include "SEEKFREE_MT9V03X.h" @@ -49,6 +48,8 @@ uint8 receive[3]; uint8 receive_num = 0; vuint8 uart_receive_flag; +uint8 link_list_num; + //Ҫõͷ int16 MT9V03X_CFG[CONFIG_FINISH][2]= { @@ -305,7 +306,7 @@ void mt9v03x_init(void) gpio_init((PIN_enum)(MT9V03X_DATA_PIN+i), GPI, 0, PULLUP); } - eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W); + link_list_num = eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W*MT9V03X_H); eru_init(MT9V03X_VSYNC_PIN, FALLING); //ʼжϣΪ½شж restoreInterrupts(interrupt_state); @@ -313,7 +314,6 @@ void mt9v03x_init(void) uint8 mt9v03x_finish_flag = 0; //һͼɼɱ־λ -uint8 now_col; //ǰڲɼ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03Xͷж // @param NULL @@ -324,16 +324,15 @@ uint8 now_col; // void mt9v03x_vsync(void) { CLEAR_GPIO_FLAG(MT9V03X_VSYNC_PIN); - now_col = 0; + if(!mt9v03x_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ { - DMA_SET_DESTINATION(MT9V03X_DMA_CH, (void *)&mt9v03x_image[0]); dma_start(MT9V03X_DMA_CH); } } - +uint8 mt9v03x_dma_int_num; //ǰDMAжϴ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03XͷDMAж // @param NULL @@ -344,16 +343,15 @@ void mt9v03x_vsync(void) void mt9v03x_dma(void) { CLEAR_DMA_FLAG(MT9V03X_DMA_CH); + mt9v03x_dma_int_num++; - now_col++; - - if(MT9V03X_H > now_col) - { - dma_start(MT9V03X_DMA_CH); - } - else + if(mt9v03x_dma_int_num >= link_list_num) { + //ɼ + mt9v03x_dma_int_num = 0; mt9v03x_finish_flag = 1;//һͼӲɼʼɼʱ3.8MS(50FPS188*120ֱ) + dma_stop(MT9V03X_DMA_CH); + } } diff --git a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h index a29edd2..0c8a785 100644 --- a/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h +++ b/Example/2-LED_Blink_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h @@ -63,9 +63,7 @@ //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ #define MT9V03X_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ - //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 - - + //ͷö typedef enum { diff --git a/Example/2-LED_Blink_Demo/USER/isr.c b/Example/2-LED_Blink_Demo/USER/isr.c index 15666f2..c6376b0 100644 --- a/Example/2-LED_Blink_Demo/USER/isr.c +++ b/Example/2-LED_Blink_Demo/USER/isr.c @@ -98,7 +98,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) if(GET_GPIO_FLAG(ERU_CH3_REQ6_P02_0))//ͨ3ж { CLEAR_GPIO_FLAG(ERU_CH3_REQ6_P02_0); - if(1 == camera_type)mt9v03x_vsync(); + if (1 == camera_type) mt9v03x_vsync(); + else if (3 == camera_type) ov7725_vsync(); } if(GET_GPIO_FLAG(ERU_CH7_REQ16_P15_1))//ͨ7ж @@ -113,7 +114,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) IFX_INTERRUPT(dma_ch5_isr, ERU_DMA_INT_SERVICE, ERU_DMA_INT_PRIO) { - if(1 == camera_type) mt9v03x_dma(); + if (1 == camera_type) mt9v03x_dma(); + else if (3 == camera_type) ov7725_dma(); } diff --git a/Example/3-PIT_Demo/Libraries/doc/version.txt b/Example/3-PIT_Demo/Libraries/doc/version.txt index b85cd50..a42bc58 100644 --- a/Example/3-PIT_Demo/Libraries/doc/version.txt +++ b/Example/3-PIT_Demo/Libraries/doc/version.txt @@ -1,9 +1,17 @@ V1.0.0 - ʼ汾 + ʼ汾 V1.0.1 ͷijжϽ޸ģжϱ־λΪ0Ųɼһͼ񣬱ַʳͻ ޸SPIʼеĴ˹̶SPI2ַ ޸STM޷ʹSTM1 - ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ \ No newline at end of file + ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ + +V1.0.2 + ޸ģIICĬʱʱΪ20 + ҪرעP20_2DzģֻĹ ע + ͷɼDMAΪlink䣬Դ󽵵DMAжϴ + ޸ĬϵIICŶ + 6050 ҪõIICģ飬ڳʼĬϵģIICʼ + С \ No newline at end of file diff --git a/Example/3-PIT_Demo/Libraries/seekfree_libraries/common/common.c b/Example/3-PIT_Demo/Libraries/seekfree_libraries/common/common.c index 0460d15..ac42b19 100644 --- a/Example/3-PIT_Demo/Libraries/seekfree_libraries/common/common.c +++ b/Example/3-PIT_Demo/Libraries/seekfree_libraries/common/common.c @@ -22,7 +22,7 @@ #include "SysSe/Bsp/Bsp.h" #include "common.h" -uint8 camera_type; +uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С diff --git a/Example/3-PIT_Demo/Libraries/seekfree_libraries/common/common.h b/Example/3-PIT_Demo/Libraries/seekfree_libraries/common/common.h index fe7ec63..13d03cd 100644 --- a/Example/3-PIT_Demo/Libraries/seekfree_libraries/common/common.h +++ b/Example/3-PIT_Demo/Libraries/seekfree_libraries/common/common.h @@ -111,7 +111,7 @@ typedef enum //ö #include -extern uint8 camera_type; +extern uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С void get_clk(void); diff --git a/Example/3-PIT_Demo/Libraries/seekfree_libraries/headfile.h b/Example/3-PIT_Demo/Libraries/seekfree_libraries/headfile.h index 0e8024f..e11bd83 100644 --- a/Example/3-PIT_Demo/Libraries/seekfree_libraries/headfile.h +++ b/Example/3-PIT_Demo/Libraries/seekfree_libraries/headfile.h @@ -62,6 +62,7 @@ #include "SEEKFREE_L3G4200D.h" #include "SEEKFREE_WIRELESS.h" #include "SEEKFREE_IPS200_PARALLEL8.h" +#include "SEEKFREE_7725.h" #endif diff --git a/Example/3-PIT_Demo/Libraries/seekfree_libraries/zf_eru_dma.c b/Example/3-PIT_Demo/Libraries/seekfree_libraries/zf_eru_dma.c index f7aab10..86c0158 100644 --- a/Example/3-PIT_Demo/Libraries/seekfree_libraries/zf_eru_dma.c +++ b/Example/3-PIT_Demo/Libraries/seekfree_libraries/zf_eru_dma.c @@ -21,9 +21,18 @@ #include "IfxDma_Dma.h" #include "IfxScuEru.h" #include "isr_config.h" +#include "zf_assert.h" #include "zf_eru_dma.h" +typedef struct +{ + Ifx_DMA_CH IFX_ALIGN(256) linked_list[8];//DMA + IfxDma_Dma_Channel channel; //DMAͨ +}DMA_LINK; + + +DMA_LINK dma_link_list; //------------------------------------------------------------------------------------------------------------------- // @brief erudmaʼ @@ -36,7 +45,7 @@ // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) { IfxDma_Dma_Channel dmaChn; //eruDMAͨ eruļeruȼΪͨ @@ -51,27 +60,85 @@ void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destinatio IfxDma_Dma_ChannelConfig cfg; IfxDma_Dma_initChannelConfig(&cfg, &dma); - cfg.transferCount = dma_count; + uint8 list_num, i; + uint16 single_channel_dma_count; + + ZF_ASSERT(!(dma_count%8));//Ϊ8ı + + + list_num = 1; + single_channel_dma_count = dma_count / list_num; + if(16384 < single_channel_dma_count) + { + while(TRUE) + { + single_channel_dma_count = dma_count / list_num; + if((single_channel_dma_count <= 16384) && !(dma_count % list_num)) + { + break; + } + list_num++; + if(list_num > 8) ZF_ASSERT(FALSE); + } + } + + + if(1 == list_num) + { + cfg.shadowControl = IfxDma_ChannelShadow_none; + cfg.operationMode = IfxDma_ChannelOperationMode_single; + cfg.shadowAddress = 0; + } + else + { + cfg.shadowControl = IfxDma_ChannelShadow_linkedList; + cfg.operationMode = IfxDma_ChannelOperationMode_continuous; + cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[1]); + } + cfg.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest; cfg.moveSize = IfxDma_ChannelMoveSize_8bit; + cfg.busPriority = IfxDma_ChannelBusPriority_high; - cfg.busPriority = IfxDma_ChannelBusPriority_high; - - cfg.sourceAddress = (unsigned)(source_addr); + cfg.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), source_addr); cfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_none; cfg.sourceCircularBufferEnabled = TRUE; - cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); cfg.destinationAddressIncrementStep = IfxDma_ChannelIncrementStep_1; - cfg.operationMode = IfxDma_ChannelOperationMode_single; - cfg.channelId = (IfxDma_ChannelId)dma_ch; - cfg.hardwareRequestEnabled = TRUE; - cfg.channelInterruptEnabled = TRUE; + cfg.channelId = (IfxDma_ChannelId)dma_ch; + cfg.hardwareRequestEnabled = FALSE; + cfg.channelInterruptEnabled = TRUE; cfg.channelInterruptPriority = ERU_DMA_INT_PRIO; cfg.channelInterruptTypeOfService = (IfxSrc_Tos)ERU_DMA_INT_SERVICE; + + + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); + + cfg.transferCount = single_channel_dma_count; + IfxDma_Dma_initChannel(&dmaChn, &cfg); + + if(1 < list_num) + { + i = 0; + while(i < list_num) + { + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr + single_channel_dma_count * i); + if(i == (list_num - 1)) cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[0]); + else cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[i+1]); + cfg.transferCount = single_channel_dma_count; + + IfxDma_Dma_initLinkedListEntry((void *)&dma_link_list.linked_list[i], &cfg); + i++; + } + } + + + IfxDma_Dma_getSrcPointer(&dma_link_list.channel)->B.CLRR = 1; + + return list_num; } diff --git a/Example/3-PIT_Demo/Libraries/seekfree_libraries/zf_eru_dma.h b/Example/3-PIT_Demo/Libraries/seekfree_libraries/zf_eru_dma.h index 50667ad..faef169 100644 --- a/Example/3-PIT_Demo/Libraries/seekfree_libraries/zf_eru_dma.h +++ b/Example/3-PIT_Demo/Libraries/seekfree_libraries/zf_eru_dma.h @@ -29,9 +29,9 @@ #define CLEAR_DMA_FLAG(dma_ch) IfxDma_clearChannelInterrupt(&MODULE_DMA, dma_ch); -#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)destination_addr) +#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr)) -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); void dma_stop(IfxDma_ChannelId dma_ch); void dma_start(IfxDma_ChannelId dma_ch); diff --git a/Example/3-PIT_Demo/Libraries/seekfree_libraries/zf_gpio.c b/Example/3-PIT_Demo/Libraries/seekfree_libraries/zf_gpio.c index 3c937cf..1d2466c 100644 --- a/Example/3-PIT_Demo/Libraries/seekfree_libraries/zf_gpio.c +++ b/Example/3-PIT_Demo/Libraries/seekfree_libraries/zf_gpio.c @@ -60,6 +60,7 @@ Ifx_P* get_port(PIN_enum pin) // @param pinmode ãòzf_gpio.hļGPIOMODE_enumöֵȷ // @return void // Sample usage: gpio_init(P00_0, GPO, 1, PUSHPULL);//P00_0ʼΪGPIOܡģʽߵƽ +// @note ҪرעP20_2DzģֻĹ //------------------------------------------------------------------------------------------------------------------- void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinmode) { diff --git a/Example/3-PIT_Demo/Libraries/seekfree_libraries/zf_gpio.h b/Example/3-PIT_Demo/Libraries/seekfree_libraries/zf_gpio.h index cfbd666..e3d144f 100644 --- a/Example/3-PIT_Demo/Libraries/seekfree_libraries/zf_gpio.h +++ b/Example/3-PIT_Demo/Libraries/seekfree_libraries/zf_gpio.h @@ -38,6 +38,15 @@ typedef enum // ö #define GET_PORT_IN_ADDR(pin) (uint8 *)(&IfxPort_getAddress((IfxPort_Index)(pin/32))->IN + pin%32/8) + + +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ + + + + //------------------------------------------------------ //ͨGPIO void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinconf); diff --git a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c new file mode 100644 index 0000000..806b8d9 --- /dev/null +++ b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c @@ -0,0 +1,262 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + +#include "IfxDma.h" +#include "IfxScuEru.h" +#include "zf_stm_systick.h" +#include "zf_gpio.h" +#include "zf_eru.h" +#include "zf_eru_dma.h" +#include "SEEKFREE_IIC.h" +#include "SEEKFREE_7725.h" + + + +IFX_ALIGN(4) uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +uint8 image_dec[OV7725_H][OV7725_W]; + +uint8 ov7725_idcode = 0; + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷڲĴʼ(ڲʹãû) +// @param NULL +// @return uint8 01ɹ +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_reg_init(void) +{ + simiic_delay_set(500); + simiic_write_reg ( OV7725_DEV_ADD, OV7725_COM7, 0x80 ); //λͷ + systick_delay_ms(STM0, 50); + ov7725_idcode = simiic_read_reg( OV7725_DEV_ADD, OV7725_VER ,SCCB); + if( ov7725_idcode != OV7725_ID ) return 0; //УͷID + + //IDȷ ȻüĴ + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM4 , 0xC1); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CLKRC , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM2 , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM3 , 0xD0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM7 , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM8 , 0xCE); //0xCE:رԶع 0xCFԶع + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSTART , 0x3F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSIZE , 0x50); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSTRT , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSIZE , 0x78); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HREF , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SCAL0 , 0x0A); + simiic_write_reg(OV7725_DEV_ADD, OV7725_AWB_Ctrl0 , 0xE0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSPAuto , 0xff); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl2 , 0x0C); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl3 , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl4 , 0x00); + + if(OV7725_W == 80) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x14); + else if(OV7725_W == 160) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x28); + else if(OV7725_W == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x3c); + else if(OV7725_W == 320) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x50); + + if(OV7725_H == 60) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x1E); + else if(OV7725_H == 120) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x3c); + else if(OV7725_H == 180) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x5a); + else if(OV7725_H == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x78); + + simiic_write_reg(OV7725_DEV_ADD, OV7725_REG28 , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCH , 0x10); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCL , 0x1F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM1 , 0x0c); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM2 , 0x16); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM3 , 0x2a); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM4 , 0x4e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM5 , 0x61); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM6 , 0x6f); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM7 , 0x7b); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM8 , 0x86); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM9 , 0x8e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM10 , 0x97); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM11 , 0xa4); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM12 , 0xaf); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM13 , 0xc5); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM14 , 0xd7); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM15 , 0xe8); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SLOP , 0x20); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_RADI , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEF , 0x13); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_XC , 0x08); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFB , 0x14); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFR , 0x17); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_CTR , 0x05); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDBase , 0x99); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDMStep , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SDE , 0x04); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BRIGHT , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CNST , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SIGN , 0x06); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ0 , 0x11); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ1 , 0x02); + + + simiic_delay_set(SIMIIC_DELAY_TIME);//޸ΪĬϵ20 + return 1; + + +} + + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷɼʼ(ڲʹãû) +// @param NULL +// @return void +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +void ov7725_port_init(void) +{ + uint8 i; + camera_type = 3;//ͷ + + //ͷɼʼ + //ʼ + for(i=0; i<8; i++) + { + gpio_init((PIN_enum)(OV7725_DATA_PIN+i), GPI, 0, PULLUP); + } + eru_dma_init(OV7725_DMA_CH, GET_PORT_IN_ADDR(OV7725_DATA_PIN), image_bin[0], OV7725_PCLK_PIN, FALLING, OV7725_DMA_NUM); + eru_init(OV7725_VSYNC_PIN, FALLING); //ʼжϣΪ½شж + +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷʼ(֮úжϺɲɼͼ) +// @param NULL +// @return 0 +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_init(void) +{ + simiic_init(); + ov7725_reg_init(); //ͷĴ + ov7725_port_init(); //ͷжżDMA + return 0; +} + + + + +uint8 ov7725_finish_flag = 0; +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбeruGPIOжϣжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_vsync(void) +{ + CLEAR_GPIO_FLAG(OV7725_VSYNC_PIN); + + if(!ov7725_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ + { + DMA_SET_DESTINATION(OV7725_DMA_CH, image_bin[0]); + dma_start(OV7725_DMA_CH); + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷDMAж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбdmaжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_dma(void) +{ + CLEAR_DMA_FLAG(OV7725_DMA_CH); + ov7725_finish_flag = 1; + dma_stop(OV7725_DMA_CH); +} + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷݽѹ +// @param *data1 Դַ +// @param *data2 Ŀĵַ +// @return void +// @since v1.0 +// Sample usage: Image_Decompression(da1,dat2[0]);//һάdat1ݽѹάdat2. +//------------------------------------------------------------------------------------------------------------------- +void image_decompression(uint8 *data1,uint8 *data2) +{ + uint8 temp[2] = {0,255}; + uint16 lenth = OV7725_SIZE; + uint8 i = 8; + + + while(lenth--) + { + i = 8; + while(i--) + { + *data2++ = temp[(*data1 >> i) & 0x01]; + } + data1++; + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷδѹͼλ鿴ͼ +// @param *imgaddr ѹͼݵַ +// @param *imgsize ͼС(ֱдOV7725_SIZE) +// @return void +// @since v1.0 +// Sample usage: øúǰȳʼuart2 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_sendimg_7725(UARTN_enum uartn) +{ + uart_putchar(uartn, 0x00);uart_putchar(uartn, 0xff);uart_putchar(uartn, 0x01);uart_putchar(uartn, 0x01);//ĸֽ + uart_putbuff(uartn, image_bin[0], OV7725_SIZE); //ٷͼ +} + + + + diff --git a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h new file mode 100644 index 0000000..e513250 --- /dev/null +++ b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h @@ -0,0 +1,243 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + + +#ifndef _SEEKFREE_7725_h +#define _SEEKFREE_7725_h + +#include "common.h" +#include "IfxDma_cfg.h" +#include "zf_uart.h" + + +//ͷID +#define OV7725_ID 0x21 + +//ͷĴ +#define OV7725_GAIN 0x00 +#define OV7725_BLUE 0x01 +#define OV7725_RED 0x02 +#define OV7725_GREEN 0x03 +#define OV7725_BAVG 0x05 +#define OV7725_GAVG 0x06 +#define OV7725_RAVG 0x07 +#define OV7725_AECH 0x08 +#define OV7725_COM2 0x09 +#define OV7725_PID 0x0A +#define OV7725_VER 0x0B +#define OV7725_COM3 0x0C +#define OV7725_COM4 0x0D +#define OV7725_COM5 0x0E +#define OV7725_COM6 0x0F +#define OV7725_AEC 0x10 +#define OV7725_CLKRC 0x11 +#define OV7725_COM7 0x12 +#define OV7725_COM8 0x13 +#define OV7725_COM9 0x14 +#define OV7725_COM10 0x15 +#define OV7725_REG16 0x16 +#define OV7725_HSTART 0x17 +#define OV7725_HSIZE 0x18 +#define OV7725_VSTRT 0x19 +#define OV7725_VSIZE 0x1A +#define OV7725_PSHFT 0x1B +#define OV7725_MIDH 0x1C +#define OV7725_MIDL 0x1D +#define OV7725_LAEC 0x1F +#define OV7725_COM11 0x20 +#define OV7725_BDBase 0x22 +#define OV7725_BDMStep 0x23 +#define OV7725_AEW 0x24 +#define OV7725_AEB 0x25 +#define OV7725_VPT 0x26 +#define OV7725_REG28 0x28 +#define OV7725_HOutSize 0x29 +#define OV7725_EXHCH 0x2A +#define OV7725_EXHCL 0x2B +#define OV7725_VOutSize 0x2C +#define OV7725_ADVFL 0x2D +#define OV7725_ADVFH 0x2E +#define OV7725_YAVE 0x2F +#define OV7725_LumHTh 0x30 +#define OV7725_LumLTh 0x31 +#define OV7725_HREF 0x32 +#define OV7725_DM_LNL 0x33 +#define OV7725_DM_LNH 0x34 +#define OV7725_ADoff_B 0x35 +#define OV7725_ADoff_R 0x36 +#define OV7725_ADoff_Gb 0x37 +#define OV7725_ADoff_Gr 0x38 +#define OV7725_Off_B 0x39 +#define OV7725_Off_R 0x3A +#define OV7725_Off_Gb 0x3B +#define OV7725_Off_Gr 0x3C +#define OV7725_COM12 0x3D +#define OV7725_COM13 0x3E +#define OV7725_COM14 0x3F +#define OV7725_COM16 0x41 +#define OV7725_TGT_B 0x42 +#define OV7725_TGT_R 0x43 +#define OV7725_TGT_Gb 0x44 +#define OV7725_TGT_Gr 0x45 +#define OV7725_LC_CTR 0x46 +#define OV7725_LC_XC 0x47 +#define OV7725_LC_YC 0x48 +#define OV7725_LC_COEF 0x49 +#define OV7725_LC_RADI 0x4A +#define OV7725_LC_COEFB 0x4B +#define OV7725_LC_COEFR 0x4C +#define OV7725_FixGain 0x4D +#define OV7725_AREF1 0x4F +#define OV7725_AREF6 0x54 +#define OV7725_UFix 0x60 +#define OV7725_VFix 0x61 +#define OV7725_AWBb_blk 0x62 +#define OV7725_AWB_Ctrl0 0x63 +#define OV7725_DSP_Ctrl1 0x64 +#define OV7725_DSP_Ctrl2 0x65 +#define OV7725_DSP_Ctrl3 0x66 +#define OV7725_DSP_Ctrl4 0x67 +#define OV7725_AWB_bias 0x68 +#define OV7725_AWBCtrl1 0x69 +#define OV7725_AWBCtrl2 0x6A +#define OV7725_AWBCtrl3 0x6B +#define OV7725_AWBCtrl4 0x6C +#define OV7725_AWBCtrl5 0x6D +#define OV7725_AWBCtrl6 0x6E +#define OV7725_AWBCtrl7 0x6F +#define OV7725_AWBCtrl8 0x70 +#define OV7725_AWBCtrl9 0x71 +#define OV7725_AWBCtrl10 0x72 +#define OV7725_AWBCtrl11 0x73 +#define OV7725_AWBCtrl12 0x74 +#define OV7725_AWBCtrl13 0x75 +#define OV7725_AWBCtrl14 0x76 +#define OV7725_AWBCtrl15 0x77 +#define OV7725_AWBCtrl16 0x78 +#define OV7725_AWBCtrl17 0x79 +#define OV7725_AWBCtrl18 0x7A +#define OV7725_AWBCtrl19 0x7B +#define OV7725_AWBCtrl20 0x7C +#define OV7725_AWBCtrl21 0x7D +#define OV7725_GAM1 0x7E +#define OV7725_GAM2 0x7F +#define OV7725_GAM3 0x80 +#define OV7725_GAM4 0x81 +#define OV7725_GAM5 0x82 +#define OV7725_GAM6 0x83 +#define OV7725_GAM7 0x84 +#define OV7725_GAM8 0x85 +#define OV7725_GAM9 0x86 +#define OV7725_GAM10 0x87 +#define OV7725_GAM11 0x88 +#define OV7725_GAM12 0x89 +#define OV7725_GAM13 0x8A +#define OV7725_GAM14 0x8B +#define OV7725_GAM15 0x8C +#define OV7725_SLOP 0x8D +#define OV7725_DNSTh 0x8E +#define OV7725_EDGE0 0x8F +#define OV7725_EDGE1 0x90 +#define OV7725_DNSOff 0x91 +#define OV7725_EDGE2 0x92 +#define OV7725_EDGE3 0x93 +#define OV7725_MTX1 0x94 +#define OV7725_MTX2 0x95 +#define OV7725_MTX3 0x96 +#define OV7725_MTX4 0x97 +#define OV7725_MTX5 0x98 +#define OV7725_MTX6 0x99 +#define OV7725_MTX_Ctrl 0x9A +#define OV7725_BRIGHT 0x9B +#define OV7725_CNST 0x9C +#define OV7725_UVADJ0 0x9E +#define OV7725_UVADJ1 0x9F +#define OV7725_SCAL0 0xA0 +#define OV7725_SCAL1 0xA1 +#define OV7725_SCAL2 0xA2 +#define OV7725_SDE 0xA6 +#define OV7725_USAT 0xA7 +#define OV7725_VSAT 0xA8 +#define OV7725_HUECOS 0xA9 +#define OV7725_HUESIN 0xAA +#define OV7725_SIGN 0xAB +#define OV7725_DSPAuto 0xAC + + +#define OV7725_DEV_ADD 0x42>>1 + + +//ͷ +#define OV7725_W 160 //ͷͼ ò 80 160 240 320 +#define OV7725_H 120 //ͷͼ߶ ò 60 120 180 240 +#define OV7725_SIZE (OV7725_W * OV7725_H/8 ) //ͼռÿռС +#define OV7725_DMA_NUM (OV7725_SIZE) //һͼDMAɼ + + +//-------------------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------------------- +#define OV7725_VSYNC_PIN ERU_CH3_REQ6_P02_0 //ж ѡΧοERU_PIN_enumö ѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DATA_PIN P00_0 //D0 D0ΪP00_0 ôD1ʹõΪP00_1 + //òP00_0P02_0P15_0Ϊ + +#define OV7725_PCLK_PIN ERU_CH2_REQ14_P02_1 //ʱ ѡΧοERU_PIN_enumö 볡жѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ + //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 + + + +extern uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +extern uint8 image_dec[OV7725_H][OV7725_W]; //ͼѹ + +extern uint8 ov7725_finish_flag; //ͼɼɱ־λ + + +// +uint8 ov7725_init(void); +void ov7725_vsync(void); +void ov7725_dma(void); +void image_decompression(uint8 *data1,uint8 *data2); +void seekfree_sendimg_7725(UARTN_enum uartn); + + + +#endif + + + diff --git a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c index 095f9e3..5d167c9 100644 --- a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c +++ b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c @@ -68,6 +68,7 @@ void icm20602_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void icm20602_init(void) { + simiic_init(); systick_delay_ms(STM0, 10); //ϵʱ // diff --git a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c index 196fd57..f56a41a 100644 --- a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c +++ b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c @@ -50,7 +50,7 @@ uint8 IIC_num; // -static uint16 simiic_delay_time=100; //ICMȴӦΪ100 +static uint16 simiic_delay_time = SIMIIC_DELAY_TIME; //ICMȴӦΪ20 //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h index 293a02a..6a9c1e3 100644 --- a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h +++ b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h @@ -34,8 +34,12 @@ -#define SEEKFREE_SCL P13_0 //SCL ΪIO -#define SEEKFREE_SDA P13_1 //SDA ΪIO +#define SEEKFREE_SCL P02_3 //SCL ΪIO +#define SEEKFREE_SDA P02_2 //SDA ΪIO + + +#define SIMIIC_DELAY_TIME 20 + typedef enum IIC //DACģ { diff --git a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c index 0f0c23a..5deb7d3 100644 --- a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c +++ b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c @@ -65,6 +65,7 @@ void l3g4200d_self_check(void) //------------------------------------------------------------------------------------------------------------------- void l3g4200d_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); l3g4200d_self_check(); diff --git a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c index c200427..8a5eec4 100644 --- a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c +++ b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c @@ -68,6 +68,7 @@ void mma8451_self_check(void) //------------------------------------------------------------------------------------------------------------------- uint8 mma845x_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); mma8451_self_check(); diff --git a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c index 0317aa0..686550d 100644 --- a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c +++ b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c @@ -71,6 +71,7 @@ void mpu6050_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void mpu6050_init(void) { + simiic_init(); systick_delay_ms(STM0, 100); //ϵʱ mpu6050_self1_check(); diff --git a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c index 014b435..05f181f 100644 --- a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c +++ b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c @@ -38,7 +38,6 @@ #include "zf_gpio.h" #include "zf_eru.h" #include "zf_eru_dma.h" -#include "stdio.h" #include "SEEKFREE_MT9V03X.h" @@ -49,6 +48,8 @@ uint8 receive[3]; uint8 receive_num = 0; vuint8 uart_receive_flag; +uint8 link_list_num; + //Ҫõͷ int16 MT9V03X_CFG[CONFIG_FINISH][2]= { @@ -305,7 +306,7 @@ void mt9v03x_init(void) gpio_init((PIN_enum)(MT9V03X_DATA_PIN+i), GPI, 0, PULLUP); } - eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W); + link_list_num = eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W*MT9V03X_H); eru_init(MT9V03X_VSYNC_PIN, FALLING); //ʼжϣΪ½شж restoreInterrupts(interrupt_state); @@ -313,7 +314,6 @@ void mt9v03x_init(void) uint8 mt9v03x_finish_flag = 0; //һͼɼɱ־λ -uint8 now_col; //ǰڲɼ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03Xͷж // @param NULL @@ -324,16 +324,15 @@ uint8 now_col; // void mt9v03x_vsync(void) { CLEAR_GPIO_FLAG(MT9V03X_VSYNC_PIN); - now_col = 0; + if(!mt9v03x_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ { - DMA_SET_DESTINATION(MT9V03X_DMA_CH, (void *)&mt9v03x_image[0]); dma_start(MT9V03X_DMA_CH); } } - +uint8 mt9v03x_dma_int_num; //ǰDMAжϴ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03XͷDMAж // @param NULL @@ -344,16 +343,15 @@ void mt9v03x_vsync(void) void mt9v03x_dma(void) { CLEAR_DMA_FLAG(MT9V03X_DMA_CH); + mt9v03x_dma_int_num++; - now_col++; - - if(MT9V03X_H > now_col) - { - dma_start(MT9V03X_DMA_CH); - } - else + if(mt9v03x_dma_int_num >= link_list_num) { + //ɼ + mt9v03x_dma_int_num = 0; mt9v03x_finish_flag = 1;//һͼӲɼʼɼʱ3.8MS(50FPS188*120ֱ) + dma_stop(MT9V03X_DMA_CH); + } } diff --git a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h index a29edd2..0c8a785 100644 --- a/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h +++ b/Example/3-PIT_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h @@ -63,9 +63,7 @@ //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ #define MT9V03X_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ - //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 - - + //ͷö typedef enum { diff --git a/Example/3-PIT_Demo/USER/isr.c b/Example/3-PIT_Demo/USER/isr.c index 2c22bb6..c6376b0 100644 --- a/Example/3-PIT_Demo/USER/isr.c +++ b/Example/3-PIT_Demo/USER/isr.c @@ -22,13 +22,9 @@ #include "isr.h" //PITжϺ ʾ - -uint16 time; IFX_INTERRUPT(cc60_pit_ch0_isr, CCU6_0_CH0_INT_SERVICE, CCU6_0_CH0_ISR_PRIORITY) { PIT_CLEAR_FLAG(CCU6_0, PIT_CH0); - time++; - printf("pit count: %d\n", time); } @@ -102,7 +98,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) if(GET_GPIO_FLAG(ERU_CH3_REQ6_P02_0))//ͨ3ж { CLEAR_GPIO_FLAG(ERU_CH3_REQ6_P02_0); - if(1 == camera_type)mt9v03x_vsync(); + if (1 == camera_type) mt9v03x_vsync(); + else if (3 == camera_type) ov7725_vsync(); } if(GET_GPIO_FLAG(ERU_CH7_REQ16_P15_1))//ͨ7ж @@ -117,7 +114,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) IFX_INTERRUPT(dma_ch5_isr, ERU_DMA_INT_SERVICE, ERU_DMA_INT_PRIO) { - if(1 == camera_type) mt9v03x_dma(); + if (1 == camera_type) mt9v03x_dma(); + else if (3 == camera_type) ov7725_dma(); } diff --git a/Example/4-Encoder_Demo/Libraries/doc/version.txt b/Example/4-Encoder_Demo/Libraries/doc/version.txt index b85cd50..a42bc58 100644 --- a/Example/4-Encoder_Demo/Libraries/doc/version.txt +++ b/Example/4-Encoder_Demo/Libraries/doc/version.txt @@ -1,9 +1,17 @@ V1.0.0 - ʼ汾 + ʼ汾 V1.0.1 ͷijжϽ޸ģжϱ־λΪ0Ųɼһͼ񣬱ַʳͻ ޸SPIʼеĴ˹̶SPI2ַ ޸STM޷ʹSTM1 - ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ \ No newline at end of file + ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ + +V1.0.2 + ޸ģIICĬʱʱΪ20 + ҪرעP20_2DzģֻĹ ע + ͷɼDMAΪlink䣬Դ󽵵DMAжϴ + ޸ĬϵIICŶ + 6050 ҪõIICģ飬ڳʼĬϵģIICʼ + С \ No newline at end of file diff --git a/Example/4-Encoder_Demo/Libraries/seekfree_libraries/common/common.c b/Example/4-Encoder_Demo/Libraries/seekfree_libraries/common/common.c index 0460d15..ac42b19 100644 --- a/Example/4-Encoder_Demo/Libraries/seekfree_libraries/common/common.c +++ b/Example/4-Encoder_Demo/Libraries/seekfree_libraries/common/common.c @@ -22,7 +22,7 @@ #include "SysSe/Bsp/Bsp.h" #include "common.h" -uint8 camera_type; +uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С diff --git a/Example/4-Encoder_Demo/Libraries/seekfree_libraries/common/common.h b/Example/4-Encoder_Demo/Libraries/seekfree_libraries/common/common.h index fe7ec63..13d03cd 100644 --- a/Example/4-Encoder_Demo/Libraries/seekfree_libraries/common/common.h +++ b/Example/4-Encoder_Demo/Libraries/seekfree_libraries/common/common.h @@ -111,7 +111,7 @@ typedef enum //ö #include -extern uint8 camera_type; +extern uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С void get_clk(void); diff --git a/Example/4-Encoder_Demo/Libraries/seekfree_libraries/headfile.h b/Example/4-Encoder_Demo/Libraries/seekfree_libraries/headfile.h index 0e8024f..e11bd83 100644 --- a/Example/4-Encoder_Demo/Libraries/seekfree_libraries/headfile.h +++ b/Example/4-Encoder_Demo/Libraries/seekfree_libraries/headfile.h @@ -62,6 +62,7 @@ #include "SEEKFREE_L3G4200D.h" #include "SEEKFREE_WIRELESS.h" #include "SEEKFREE_IPS200_PARALLEL8.h" +#include "SEEKFREE_7725.h" #endif diff --git a/Example/4-Encoder_Demo/Libraries/seekfree_libraries/zf_eru_dma.c b/Example/4-Encoder_Demo/Libraries/seekfree_libraries/zf_eru_dma.c index f7aab10..86c0158 100644 --- a/Example/4-Encoder_Demo/Libraries/seekfree_libraries/zf_eru_dma.c +++ b/Example/4-Encoder_Demo/Libraries/seekfree_libraries/zf_eru_dma.c @@ -21,9 +21,18 @@ #include "IfxDma_Dma.h" #include "IfxScuEru.h" #include "isr_config.h" +#include "zf_assert.h" #include "zf_eru_dma.h" +typedef struct +{ + Ifx_DMA_CH IFX_ALIGN(256) linked_list[8];//DMA + IfxDma_Dma_Channel channel; //DMAͨ +}DMA_LINK; + + +DMA_LINK dma_link_list; //------------------------------------------------------------------------------------------------------------------- // @brief erudmaʼ @@ -36,7 +45,7 @@ // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) { IfxDma_Dma_Channel dmaChn; //eruDMAͨ eruļeruȼΪͨ @@ -51,27 +60,85 @@ void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destinatio IfxDma_Dma_ChannelConfig cfg; IfxDma_Dma_initChannelConfig(&cfg, &dma); - cfg.transferCount = dma_count; + uint8 list_num, i; + uint16 single_channel_dma_count; + + ZF_ASSERT(!(dma_count%8));//Ϊ8ı + + + list_num = 1; + single_channel_dma_count = dma_count / list_num; + if(16384 < single_channel_dma_count) + { + while(TRUE) + { + single_channel_dma_count = dma_count / list_num; + if((single_channel_dma_count <= 16384) && !(dma_count % list_num)) + { + break; + } + list_num++; + if(list_num > 8) ZF_ASSERT(FALSE); + } + } + + + if(1 == list_num) + { + cfg.shadowControl = IfxDma_ChannelShadow_none; + cfg.operationMode = IfxDma_ChannelOperationMode_single; + cfg.shadowAddress = 0; + } + else + { + cfg.shadowControl = IfxDma_ChannelShadow_linkedList; + cfg.operationMode = IfxDma_ChannelOperationMode_continuous; + cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[1]); + } + cfg.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest; cfg.moveSize = IfxDma_ChannelMoveSize_8bit; + cfg.busPriority = IfxDma_ChannelBusPriority_high; - cfg.busPriority = IfxDma_ChannelBusPriority_high; - - cfg.sourceAddress = (unsigned)(source_addr); + cfg.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), source_addr); cfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_none; cfg.sourceCircularBufferEnabled = TRUE; - cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); cfg.destinationAddressIncrementStep = IfxDma_ChannelIncrementStep_1; - cfg.operationMode = IfxDma_ChannelOperationMode_single; - cfg.channelId = (IfxDma_ChannelId)dma_ch; - cfg.hardwareRequestEnabled = TRUE; - cfg.channelInterruptEnabled = TRUE; + cfg.channelId = (IfxDma_ChannelId)dma_ch; + cfg.hardwareRequestEnabled = FALSE; + cfg.channelInterruptEnabled = TRUE; cfg.channelInterruptPriority = ERU_DMA_INT_PRIO; cfg.channelInterruptTypeOfService = (IfxSrc_Tos)ERU_DMA_INT_SERVICE; + + + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); + + cfg.transferCount = single_channel_dma_count; + IfxDma_Dma_initChannel(&dmaChn, &cfg); + + if(1 < list_num) + { + i = 0; + while(i < list_num) + { + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr + single_channel_dma_count * i); + if(i == (list_num - 1)) cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[0]); + else cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[i+1]); + cfg.transferCount = single_channel_dma_count; + + IfxDma_Dma_initLinkedListEntry((void *)&dma_link_list.linked_list[i], &cfg); + i++; + } + } + + + IfxDma_Dma_getSrcPointer(&dma_link_list.channel)->B.CLRR = 1; + + return list_num; } diff --git a/Example/4-Encoder_Demo/Libraries/seekfree_libraries/zf_eru_dma.h b/Example/4-Encoder_Demo/Libraries/seekfree_libraries/zf_eru_dma.h index 50667ad..faef169 100644 --- a/Example/4-Encoder_Demo/Libraries/seekfree_libraries/zf_eru_dma.h +++ b/Example/4-Encoder_Demo/Libraries/seekfree_libraries/zf_eru_dma.h @@ -29,9 +29,9 @@ #define CLEAR_DMA_FLAG(dma_ch) IfxDma_clearChannelInterrupt(&MODULE_DMA, dma_ch); -#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)destination_addr) +#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr)) -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); void dma_stop(IfxDma_ChannelId dma_ch); void dma_start(IfxDma_ChannelId dma_ch); diff --git a/Example/4-Encoder_Demo/Libraries/seekfree_libraries/zf_gpio.c b/Example/4-Encoder_Demo/Libraries/seekfree_libraries/zf_gpio.c index 3c937cf..1d2466c 100644 --- a/Example/4-Encoder_Demo/Libraries/seekfree_libraries/zf_gpio.c +++ b/Example/4-Encoder_Demo/Libraries/seekfree_libraries/zf_gpio.c @@ -60,6 +60,7 @@ Ifx_P* get_port(PIN_enum pin) // @param pinmode ãòzf_gpio.hļGPIOMODE_enumöֵȷ // @return void // Sample usage: gpio_init(P00_0, GPO, 1, PUSHPULL);//P00_0ʼΪGPIOܡģʽߵƽ +// @note ҪرעP20_2DzģֻĹ //------------------------------------------------------------------------------------------------------------------- void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinmode) { diff --git a/Example/4-Encoder_Demo/Libraries/seekfree_libraries/zf_gpio.h b/Example/4-Encoder_Demo/Libraries/seekfree_libraries/zf_gpio.h index cfbd666..e3d144f 100644 --- a/Example/4-Encoder_Demo/Libraries/seekfree_libraries/zf_gpio.h +++ b/Example/4-Encoder_Demo/Libraries/seekfree_libraries/zf_gpio.h @@ -38,6 +38,15 @@ typedef enum // ö #define GET_PORT_IN_ADDR(pin) (uint8 *)(&IfxPort_getAddress((IfxPort_Index)(pin/32))->IN + pin%32/8) + + +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ + + + + //------------------------------------------------------ //ͨGPIO void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinconf); diff --git a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c new file mode 100644 index 0000000..806b8d9 --- /dev/null +++ b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c @@ -0,0 +1,262 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + +#include "IfxDma.h" +#include "IfxScuEru.h" +#include "zf_stm_systick.h" +#include "zf_gpio.h" +#include "zf_eru.h" +#include "zf_eru_dma.h" +#include "SEEKFREE_IIC.h" +#include "SEEKFREE_7725.h" + + + +IFX_ALIGN(4) uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +uint8 image_dec[OV7725_H][OV7725_W]; + +uint8 ov7725_idcode = 0; + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷڲĴʼ(ڲʹãû) +// @param NULL +// @return uint8 01ɹ +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_reg_init(void) +{ + simiic_delay_set(500); + simiic_write_reg ( OV7725_DEV_ADD, OV7725_COM7, 0x80 ); //λͷ + systick_delay_ms(STM0, 50); + ov7725_idcode = simiic_read_reg( OV7725_DEV_ADD, OV7725_VER ,SCCB); + if( ov7725_idcode != OV7725_ID ) return 0; //УͷID + + //IDȷ ȻüĴ + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM4 , 0xC1); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CLKRC , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM2 , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM3 , 0xD0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM7 , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM8 , 0xCE); //0xCE:رԶع 0xCFԶع + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSTART , 0x3F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSIZE , 0x50); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSTRT , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSIZE , 0x78); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HREF , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SCAL0 , 0x0A); + simiic_write_reg(OV7725_DEV_ADD, OV7725_AWB_Ctrl0 , 0xE0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSPAuto , 0xff); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl2 , 0x0C); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl3 , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl4 , 0x00); + + if(OV7725_W == 80) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x14); + else if(OV7725_W == 160) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x28); + else if(OV7725_W == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x3c); + else if(OV7725_W == 320) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x50); + + if(OV7725_H == 60) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x1E); + else if(OV7725_H == 120) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x3c); + else if(OV7725_H == 180) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x5a); + else if(OV7725_H == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x78); + + simiic_write_reg(OV7725_DEV_ADD, OV7725_REG28 , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCH , 0x10); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCL , 0x1F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM1 , 0x0c); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM2 , 0x16); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM3 , 0x2a); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM4 , 0x4e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM5 , 0x61); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM6 , 0x6f); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM7 , 0x7b); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM8 , 0x86); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM9 , 0x8e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM10 , 0x97); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM11 , 0xa4); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM12 , 0xaf); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM13 , 0xc5); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM14 , 0xd7); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM15 , 0xe8); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SLOP , 0x20); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_RADI , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEF , 0x13); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_XC , 0x08); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFB , 0x14); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFR , 0x17); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_CTR , 0x05); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDBase , 0x99); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDMStep , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SDE , 0x04); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BRIGHT , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CNST , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SIGN , 0x06); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ0 , 0x11); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ1 , 0x02); + + + simiic_delay_set(SIMIIC_DELAY_TIME);//޸ΪĬϵ20 + return 1; + + +} + + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷɼʼ(ڲʹãû) +// @param NULL +// @return void +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +void ov7725_port_init(void) +{ + uint8 i; + camera_type = 3;//ͷ + + //ͷɼʼ + //ʼ + for(i=0; i<8; i++) + { + gpio_init((PIN_enum)(OV7725_DATA_PIN+i), GPI, 0, PULLUP); + } + eru_dma_init(OV7725_DMA_CH, GET_PORT_IN_ADDR(OV7725_DATA_PIN), image_bin[0], OV7725_PCLK_PIN, FALLING, OV7725_DMA_NUM); + eru_init(OV7725_VSYNC_PIN, FALLING); //ʼжϣΪ½شж + +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷʼ(֮úжϺɲɼͼ) +// @param NULL +// @return 0 +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_init(void) +{ + simiic_init(); + ov7725_reg_init(); //ͷĴ + ov7725_port_init(); //ͷжżDMA + return 0; +} + + + + +uint8 ov7725_finish_flag = 0; +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбeruGPIOжϣжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_vsync(void) +{ + CLEAR_GPIO_FLAG(OV7725_VSYNC_PIN); + + if(!ov7725_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ + { + DMA_SET_DESTINATION(OV7725_DMA_CH, image_bin[0]); + dma_start(OV7725_DMA_CH); + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷDMAж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбdmaжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_dma(void) +{ + CLEAR_DMA_FLAG(OV7725_DMA_CH); + ov7725_finish_flag = 1; + dma_stop(OV7725_DMA_CH); +} + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷݽѹ +// @param *data1 Դַ +// @param *data2 Ŀĵַ +// @return void +// @since v1.0 +// Sample usage: Image_Decompression(da1,dat2[0]);//һάdat1ݽѹάdat2. +//------------------------------------------------------------------------------------------------------------------- +void image_decompression(uint8 *data1,uint8 *data2) +{ + uint8 temp[2] = {0,255}; + uint16 lenth = OV7725_SIZE; + uint8 i = 8; + + + while(lenth--) + { + i = 8; + while(i--) + { + *data2++ = temp[(*data1 >> i) & 0x01]; + } + data1++; + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷδѹͼλ鿴ͼ +// @param *imgaddr ѹͼݵַ +// @param *imgsize ͼС(ֱдOV7725_SIZE) +// @return void +// @since v1.0 +// Sample usage: øúǰȳʼuart2 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_sendimg_7725(UARTN_enum uartn) +{ + uart_putchar(uartn, 0x00);uart_putchar(uartn, 0xff);uart_putchar(uartn, 0x01);uart_putchar(uartn, 0x01);//ĸֽ + uart_putbuff(uartn, image_bin[0], OV7725_SIZE); //ٷͼ +} + + + + diff --git a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h new file mode 100644 index 0000000..e513250 --- /dev/null +++ b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h @@ -0,0 +1,243 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + + +#ifndef _SEEKFREE_7725_h +#define _SEEKFREE_7725_h + +#include "common.h" +#include "IfxDma_cfg.h" +#include "zf_uart.h" + + +//ͷID +#define OV7725_ID 0x21 + +//ͷĴ +#define OV7725_GAIN 0x00 +#define OV7725_BLUE 0x01 +#define OV7725_RED 0x02 +#define OV7725_GREEN 0x03 +#define OV7725_BAVG 0x05 +#define OV7725_GAVG 0x06 +#define OV7725_RAVG 0x07 +#define OV7725_AECH 0x08 +#define OV7725_COM2 0x09 +#define OV7725_PID 0x0A +#define OV7725_VER 0x0B +#define OV7725_COM3 0x0C +#define OV7725_COM4 0x0D +#define OV7725_COM5 0x0E +#define OV7725_COM6 0x0F +#define OV7725_AEC 0x10 +#define OV7725_CLKRC 0x11 +#define OV7725_COM7 0x12 +#define OV7725_COM8 0x13 +#define OV7725_COM9 0x14 +#define OV7725_COM10 0x15 +#define OV7725_REG16 0x16 +#define OV7725_HSTART 0x17 +#define OV7725_HSIZE 0x18 +#define OV7725_VSTRT 0x19 +#define OV7725_VSIZE 0x1A +#define OV7725_PSHFT 0x1B +#define OV7725_MIDH 0x1C +#define OV7725_MIDL 0x1D +#define OV7725_LAEC 0x1F +#define OV7725_COM11 0x20 +#define OV7725_BDBase 0x22 +#define OV7725_BDMStep 0x23 +#define OV7725_AEW 0x24 +#define OV7725_AEB 0x25 +#define OV7725_VPT 0x26 +#define OV7725_REG28 0x28 +#define OV7725_HOutSize 0x29 +#define OV7725_EXHCH 0x2A +#define OV7725_EXHCL 0x2B +#define OV7725_VOutSize 0x2C +#define OV7725_ADVFL 0x2D +#define OV7725_ADVFH 0x2E +#define OV7725_YAVE 0x2F +#define OV7725_LumHTh 0x30 +#define OV7725_LumLTh 0x31 +#define OV7725_HREF 0x32 +#define OV7725_DM_LNL 0x33 +#define OV7725_DM_LNH 0x34 +#define OV7725_ADoff_B 0x35 +#define OV7725_ADoff_R 0x36 +#define OV7725_ADoff_Gb 0x37 +#define OV7725_ADoff_Gr 0x38 +#define OV7725_Off_B 0x39 +#define OV7725_Off_R 0x3A +#define OV7725_Off_Gb 0x3B +#define OV7725_Off_Gr 0x3C +#define OV7725_COM12 0x3D +#define OV7725_COM13 0x3E +#define OV7725_COM14 0x3F +#define OV7725_COM16 0x41 +#define OV7725_TGT_B 0x42 +#define OV7725_TGT_R 0x43 +#define OV7725_TGT_Gb 0x44 +#define OV7725_TGT_Gr 0x45 +#define OV7725_LC_CTR 0x46 +#define OV7725_LC_XC 0x47 +#define OV7725_LC_YC 0x48 +#define OV7725_LC_COEF 0x49 +#define OV7725_LC_RADI 0x4A +#define OV7725_LC_COEFB 0x4B +#define OV7725_LC_COEFR 0x4C +#define OV7725_FixGain 0x4D +#define OV7725_AREF1 0x4F +#define OV7725_AREF6 0x54 +#define OV7725_UFix 0x60 +#define OV7725_VFix 0x61 +#define OV7725_AWBb_blk 0x62 +#define OV7725_AWB_Ctrl0 0x63 +#define OV7725_DSP_Ctrl1 0x64 +#define OV7725_DSP_Ctrl2 0x65 +#define OV7725_DSP_Ctrl3 0x66 +#define OV7725_DSP_Ctrl4 0x67 +#define OV7725_AWB_bias 0x68 +#define OV7725_AWBCtrl1 0x69 +#define OV7725_AWBCtrl2 0x6A +#define OV7725_AWBCtrl3 0x6B +#define OV7725_AWBCtrl4 0x6C +#define OV7725_AWBCtrl5 0x6D +#define OV7725_AWBCtrl6 0x6E +#define OV7725_AWBCtrl7 0x6F +#define OV7725_AWBCtrl8 0x70 +#define OV7725_AWBCtrl9 0x71 +#define OV7725_AWBCtrl10 0x72 +#define OV7725_AWBCtrl11 0x73 +#define OV7725_AWBCtrl12 0x74 +#define OV7725_AWBCtrl13 0x75 +#define OV7725_AWBCtrl14 0x76 +#define OV7725_AWBCtrl15 0x77 +#define OV7725_AWBCtrl16 0x78 +#define OV7725_AWBCtrl17 0x79 +#define OV7725_AWBCtrl18 0x7A +#define OV7725_AWBCtrl19 0x7B +#define OV7725_AWBCtrl20 0x7C +#define OV7725_AWBCtrl21 0x7D +#define OV7725_GAM1 0x7E +#define OV7725_GAM2 0x7F +#define OV7725_GAM3 0x80 +#define OV7725_GAM4 0x81 +#define OV7725_GAM5 0x82 +#define OV7725_GAM6 0x83 +#define OV7725_GAM7 0x84 +#define OV7725_GAM8 0x85 +#define OV7725_GAM9 0x86 +#define OV7725_GAM10 0x87 +#define OV7725_GAM11 0x88 +#define OV7725_GAM12 0x89 +#define OV7725_GAM13 0x8A +#define OV7725_GAM14 0x8B +#define OV7725_GAM15 0x8C +#define OV7725_SLOP 0x8D +#define OV7725_DNSTh 0x8E +#define OV7725_EDGE0 0x8F +#define OV7725_EDGE1 0x90 +#define OV7725_DNSOff 0x91 +#define OV7725_EDGE2 0x92 +#define OV7725_EDGE3 0x93 +#define OV7725_MTX1 0x94 +#define OV7725_MTX2 0x95 +#define OV7725_MTX3 0x96 +#define OV7725_MTX4 0x97 +#define OV7725_MTX5 0x98 +#define OV7725_MTX6 0x99 +#define OV7725_MTX_Ctrl 0x9A +#define OV7725_BRIGHT 0x9B +#define OV7725_CNST 0x9C +#define OV7725_UVADJ0 0x9E +#define OV7725_UVADJ1 0x9F +#define OV7725_SCAL0 0xA0 +#define OV7725_SCAL1 0xA1 +#define OV7725_SCAL2 0xA2 +#define OV7725_SDE 0xA6 +#define OV7725_USAT 0xA7 +#define OV7725_VSAT 0xA8 +#define OV7725_HUECOS 0xA9 +#define OV7725_HUESIN 0xAA +#define OV7725_SIGN 0xAB +#define OV7725_DSPAuto 0xAC + + +#define OV7725_DEV_ADD 0x42>>1 + + +//ͷ +#define OV7725_W 160 //ͷͼ ò 80 160 240 320 +#define OV7725_H 120 //ͷͼ߶ ò 60 120 180 240 +#define OV7725_SIZE (OV7725_W * OV7725_H/8 ) //ͼռÿռС +#define OV7725_DMA_NUM (OV7725_SIZE) //һͼDMAɼ + + +//-------------------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------------------- +#define OV7725_VSYNC_PIN ERU_CH3_REQ6_P02_0 //ж ѡΧοERU_PIN_enumö ѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DATA_PIN P00_0 //D0 D0ΪP00_0 ôD1ʹõΪP00_1 + //òP00_0P02_0P15_0Ϊ + +#define OV7725_PCLK_PIN ERU_CH2_REQ14_P02_1 //ʱ ѡΧοERU_PIN_enumö 볡жѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ + //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 + + + +extern uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +extern uint8 image_dec[OV7725_H][OV7725_W]; //ͼѹ + +extern uint8 ov7725_finish_flag; //ͼɼɱ־λ + + +// +uint8 ov7725_init(void); +void ov7725_vsync(void); +void ov7725_dma(void); +void image_decompression(uint8 *data1,uint8 *data2); +void seekfree_sendimg_7725(UARTN_enum uartn); + + + +#endif + + + diff --git a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c index 095f9e3..5d167c9 100644 --- a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c +++ b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c @@ -68,6 +68,7 @@ void icm20602_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void icm20602_init(void) { + simiic_init(); systick_delay_ms(STM0, 10); //ϵʱ // diff --git a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c index 196fd57..f56a41a 100644 --- a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c +++ b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c @@ -50,7 +50,7 @@ uint8 IIC_num; // -static uint16 simiic_delay_time=100; //ICMȴӦΪ100 +static uint16 simiic_delay_time = SIMIIC_DELAY_TIME; //ICMȴӦΪ20 //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h index 293a02a..6a9c1e3 100644 --- a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h +++ b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h @@ -34,8 +34,12 @@ -#define SEEKFREE_SCL P13_0 //SCL ΪIO -#define SEEKFREE_SDA P13_1 //SDA ΪIO +#define SEEKFREE_SCL P02_3 //SCL ΪIO +#define SEEKFREE_SDA P02_2 //SDA ΪIO + + +#define SIMIIC_DELAY_TIME 20 + typedef enum IIC //DACģ { diff --git a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c index 0f0c23a..5deb7d3 100644 --- a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c +++ b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c @@ -65,6 +65,7 @@ void l3g4200d_self_check(void) //------------------------------------------------------------------------------------------------------------------- void l3g4200d_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); l3g4200d_self_check(); diff --git a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c index c200427..8a5eec4 100644 --- a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c +++ b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c @@ -68,6 +68,7 @@ void mma8451_self_check(void) //------------------------------------------------------------------------------------------------------------------- uint8 mma845x_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); mma8451_self_check(); diff --git a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c index 0317aa0..686550d 100644 --- a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c +++ b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c @@ -71,6 +71,7 @@ void mpu6050_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void mpu6050_init(void) { + simiic_init(); systick_delay_ms(STM0, 100); //ϵʱ mpu6050_self1_check(); diff --git a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c index 014b435..05f181f 100644 --- a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c +++ b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c @@ -38,7 +38,6 @@ #include "zf_gpio.h" #include "zf_eru.h" #include "zf_eru_dma.h" -#include "stdio.h" #include "SEEKFREE_MT9V03X.h" @@ -49,6 +48,8 @@ uint8 receive[3]; uint8 receive_num = 0; vuint8 uart_receive_flag; +uint8 link_list_num; + //Ҫõͷ int16 MT9V03X_CFG[CONFIG_FINISH][2]= { @@ -305,7 +306,7 @@ void mt9v03x_init(void) gpio_init((PIN_enum)(MT9V03X_DATA_PIN+i), GPI, 0, PULLUP); } - eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W); + link_list_num = eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W*MT9V03X_H); eru_init(MT9V03X_VSYNC_PIN, FALLING); //ʼжϣΪ½شж restoreInterrupts(interrupt_state); @@ -313,7 +314,6 @@ void mt9v03x_init(void) uint8 mt9v03x_finish_flag = 0; //һͼɼɱ־λ -uint8 now_col; //ǰڲɼ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03Xͷж // @param NULL @@ -324,16 +324,15 @@ uint8 now_col; // void mt9v03x_vsync(void) { CLEAR_GPIO_FLAG(MT9V03X_VSYNC_PIN); - now_col = 0; + if(!mt9v03x_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ { - DMA_SET_DESTINATION(MT9V03X_DMA_CH, (void *)&mt9v03x_image[0]); dma_start(MT9V03X_DMA_CH); } } - +uint8 mt9v03x_dma_int_num; //ǰDMAжϴ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03XͷDMAж // @param NULL @@ -344,16 +343,15 @@ void mt9v03x_vsync(void) void mt9v03x_dma(void) { CLEAR_DMA_FLAG(MT9V03X_DMA_CH); + mt9v03x_dma_int_num++; - now_col++; - - if(MT9V03X_H > now_col) - { - dma_start(MT9V03X_DMA_CH); - } - else + if(mt9v03x_dma_int_num >= link_list_num) { + //ɼ + mt9v03x_dma_int_num = 0; mt9v03x_finish_flag = 1;//һͼӲɼʼɼʱ3.8MS(50FPS188*120ֱ) + dma_stop(MT9V03X_DMA_CH); + } } diff --git a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h index a29edd2..0c8a785 100644 --- a/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h +++ b/Example/4-Encoder_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h @@ -63,9 +63,7 @@ //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ #define MT9V03X_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ - //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 - - + //ͷö typedef enum { diff --git a/Example/4-Encoder_Demo/USER/isr.c b/Example/4-Encoder_Demo/USER/isr.c index 15666f2..c6376b0 100644 --- a/Example/4-Encoder_Demo/USER/isr.c +++ b/Example/4-Encoder_Demo/USER/isr.c @@ -98,7 +98,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) if(GET_GPIO_FLAG(ERU_CH3_REQ6_P02_0))//ͨ3ж { CLEAR_GPIO_FLAG(ERU_CH3_REQ6_P02_0); - if(1 == camera_type)mt9v03x_vsync(); + if (1 == camera_type) mt9v03x_vsync(); + else if (3 == camera_type) ov7725_vsync(); } if(GET_GPIO_FLAG(ERU_CH7_REQ16_P15_1))//ͨ7ж @@ -113,7 +114,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) IFX_INTERRUPT(dma_ch5_isr, ERU_DMA_INT_SERVICE, ERU_DMA_INT_PRIO) { - if(1 == camera_type) mt9v03x_dma(); + if (1 == camera_type) mt9v03x_dma(); + else if (3 == camera_type) ov7725_dma(); } diff --git a/Example/5-UART_Demo/Libraries/doc/version.txt b/Example/5-UART_Demo/Libraries/doc/version.txt index b85cd50..a42bc58 100644 --- a/Example/5-UART_Demo/Libraries/doc/version.txt +++ b/Example/5-UART_Demo/Libraries/doc/version.txt @@ -1,9 +1,17 @@ V1.0.0 - ʼ汾 + ʼ汾 V1.0.1 ͷijжϽ޸ģжϱ־λΪ0Ųɼһͼ񣬱ַʳͻ ޸SPIʼеĴ˹̶SPI2ַ ޸STM޷ʹSTM1 - ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ \ No newline at end of file + ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ + +V1.0.2 + ޸ģIICĬʱʱΪ20 + ҪرעP20_2DzģֻĹ ע + ͷɼDMAΪlink䣬Դ󽵵DMAжϴ + ޸ĬϵIICŶ + 6050 ҪõIICģ飬ڳʼĬϵģIICʼ + С \ No newline at end of file diff --git a/Example/5-UART_Demo/Libraries/seekfree_libraries/common/common.c b/Example/5-UART_Demo/Libraries/seekfree_libraries/common/common.c index 0460d15..ac42b19 100644 --- a/Example/5-UART_Demo/Libraries/seekfree_libraries/common/common.c +++ b/Example/5-UART_Demo/Libraries/seekfree_libraries/common/common.c @@ -22,7 +22,7 @@ #include "SysSe/Bsp/Bsp.h" #include "common.h" -uint8 camera_type; +uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С diff --git a/Example/5-UART_Demo/Libraries/seekfree_libraries/common/common.h b/Example/5-UART_Demo/Libraries/seekfree_libraries/common/common.h index fe7ec63..13d03cd 100644 --- a/Example/5-UART_Demo/Libraries/seekfree_libraries/common/common.h +++ b/Example/5-UART_Demo/Libraries/seekfree_libraries/common/common.h @@ -111,7 +111,7 @@ typedef enum //ö #include -extern uint8 camera_type; +extern uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С void get_clk(void); diff --git a/Example/5-UART_Demo/Libraries/seekfree_libraries/headfile.h b/Example/5-UART_Demo/Libraries/seekfree_libraries/headfile.h index 0e8024f..e11bd83 100644 --- a/Example/5-UART_Demo/Libraries/seekfree_libraries/headfile.h +++ b/Example/5-UART_Demo/Libraries/seekfree_libraries/headfile.h @@ -62,6 +62,7 @@ #include "SEEKFREE_L3G4200D.h" #include "SEEKFREE_WIRELESS.h" #include "SEEKFREE_IPS200_PARALLEL8.h" +#include "SEEKFREE_7725.h" #endif diff --git a/Example/5-UART_Demo/Libraries/seekfree_libraries/zf_eru_dma.c b/Example/5-UART_Demo/Libraries/seekfree_libraries/zf_eru_dma.c index f7aab10..86c0158 100644 --- a/Example/5-UART_Demo/Libraries/seekfree_libraries/zf_eru_dma.c +++ b/Example/5-UART_Demo/Libraries/seekfree_libraries/zf_eru_dma.c @@ -21,9 +21,18 @@ #include "IfxDma_Dma.h" #include "IfxScuEru.h" #include "isr_config.h" +#include "zf_assert.h" #include "zf_eru_dma.h" +typedef struct +{ + Ifx_DMA_CH IFX_ALIGN(256) linked_list[8];//DMA + IfxDma_Dma_Channel channel; //DMAͨ +}DMA_LINK; + + +DMA_LINK dma_link_list; //------------------------------------------------------------------------------------------------------------------- // @brief erudmaʼ @@ -36,7 +45,7 @@ // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) { IfxDma_Dma_Channel dmaChn; //eruDMAͨ eruļeruȼΪͨ @@ -51,27 +60,85 @@ void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destinatio IfxDma_Dma_ChannelConfig cfg; IfxDma_Dma_initChannelConfig(&cfg, &dma); - cfg.transferCount = dma_count; + uint8 list_num, i; + uint16 single_channel_dma_count; + + ZF_ASSERT(!(dma_count%8));//Ϊ8ı + + + list_num = 1; + single_channel_dma_count = dma_count / list_num; + if(16384 < single_channel_dma_count) + { + while(TRUE) + { + single_channel_dma_count = dma_count / list_num; + if((single_channel_dma_count <= 16384) && !(dma_count % list_num)) + { + break; + } + list_num++; + if(list_num > 8) ZF_ASSERT(FALSE); + } + } + + + if(1 == list_num) + { + cfg.shadowControl = IfxDma_ChannelShadow_none; + cfg.operationMode = IfxDma_ChannelOperationMode_single; + cfg.shadowAddress = 0; + } + else + { + cfg.shadowControl = IfxDma_ChannelShadow_linkedList; + cfg.operationMode = IfxDma_ChannelOperationMode_continuous; + cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[1]); + } + cfg.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest; cfg.moveSize = IfxDma_ChannelMoveSize_8bit; + cfg.busPriority = IfxDma_ChannelBusPriority_high; - cfg.busPriority = IfxDma_ChannelBusPriority_high; - - cfg.sourceAddress = (unsigned)(source_addr); + cfg.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), source_addr); cfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_none; cfg.sourceCircularBufferEnabled = TRUE; - cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); cfg.destinationAddressIncrementStep = IfxDma_ChannelIncrementStep_1; - cfg.operationMode = IfxDma_ChannelOperationMode_single; - cfg.channelId = (IfxDma_ChannelId)dma_ch; - cfg.hardwareRequestEnabled = TRUE; - cfg.channelInterruptEnabled = TRUE; + cfg.channelId = (IfxDma_ChannelId)dma_ch; + cfg.hardwareRequestEnabled = FALSE; + cfg.channelInterruptEnabled = TRUE; cfg.channelInterruptPriority = ERU_DMA_INT_PRIO; cfg.channelInterruptTypeOfService = (IfxSrc_Tos)ERU_DMA_INT_SERVICE; + + + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); + + cfg.transferCount = single_channel_dma_count; + IfxDma_Dma_initChannel(&dmaChn, &cfg); + + if(1 < list_num) + { + i = 0; + while(i < list_num) + { + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr + single_channel_dma_count * i); + if(i == (list_num - 1)) cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[0]); + else cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[i+1]); + cfg.transferCount = single_channel_dma_count; + + IfxDma_Dma_initLinkedListEntry((void *)&dma_link_list.linked_list[i], &cfg); + i++; + } + } + + + IfxDma_Dma_getSrcPointer(&dma_link_list.channel)->B.CLRR = 1; + + return list_num; } diff --git a/Example/5-UART_Demo/Libraries/seekfree_libraries/zf_eru_dma.h b/Example/5-UART_Demo/Libraries/seekfree_libraries/zf_eru_dma.h index 50667ad..faef169 100644 --- a/Example/5-UART_Demo/Libraries/seekfree_libraries/zf_eru_dma.h +++ b/Example/5-UART_Demo/Libraries/seekfree_libraries/zf_eru_dma.h @@ -29,9 +29,9 @@ #define CLEAR_DMA_FLAG(dma_ch) IfxDma_clearChannelInterrupt(&MODULE_DMA, dma_ch); -#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)destination_addr) +#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr)) -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); void dma_stop(IfxDma_ChannelId dma_ch); void dma_start(IfxDma_ChannelId dma_ch); diff --git a/Example/5-UART_Demo/Libraries/seekfree_libraries/zf_gpio.c b/Example/5-UART_Demo/Libraries/seekfree_libraries/zf_gpio.c index 3c937cf..1d2466c 100644 --- a/Example/5-UART_Demo/Libraries/seekfree_libraries/zf_gpio.c +++ b/Example/5-UART_Demo/Libraries/seekfree_libraries/zf_gpio.c @@ -60,6 +60,7 @@ Ifx_P* get_port(PIN_enum pin) // @param pinmode ãòzf_gpio.hļGPIOMODE_enumöֵȷ // @return void // Sample usage: gpio_init(P00_0, GPO, 1, PUSHPULL);//P00_0ʼΪGPIOܡģʽߵƽ +// @note ҪرעP20_2DzģֻĹ //------------------------------------------------------------------------------------------------------------------- void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinmode) { diff --git a/Example/5-UART_Demo/Libraries/seekfree_libraries/zf_gpio.h b/Example/5-UART_Demo/Libraries/seekfree_libraries/zf_gpio.h index cfbd666..e3d144f 100644 --- a/Example/5-UART_Demo/Libraries/seekfree_libraries/zf_gpio.h +++ b/Example/5-UART_Demo/Libraries/seekfree_libraries/zf_gpio.h @@ -38,6 +38,15 @@ typedef enum // ö #define GET_PORT_IN_ADDR(pin) (uint8 *)(&IfxPort_getAddress((IfxPort_Index)(pin/32))->IN + pin%32/8) + + +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ + + + + //------------------------------------------------------ //ͨGPIO void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinconf); diff --git a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c new file mode 100644 index 0000000..806b8d9 --- /dev/null +++ b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c @@ -0,0 +1,262 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + +#include "IfxDma.h" +#include "IfxScuEru.h" +#include "zf_stm_systick.h" +#include "zf_gpio.h" +#include "zf_eru.h" +#include "zf_eru_dma.h" +#include "SEEKFREE_IIC.h" +#include "SEEKFREE_7725.h" + + + +IFX_ALIGN(4) uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +uint8 image_dec[OV7725_H][OV7725_W]; + +uint8 ov7725_idcode = 0; + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷڲĴʼ(ڲʹãû) +// @param NULL +// @return uint8 01ɹ +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_reg_init(void) +{ + simiic_delay_set(500); + simiic_write_reg ( OV7725_DEV_ADD, OV7725_COM7, 0x80 ); //λͷ + systick_delay_ms(STM0, 50); + ov7725_idcode = simiic_read_reg( OV7725_DEV_ADD, OV7725_VER ,SCCB); + if( ov7725_idcode != OV7725_ID ) return 0; //УͷID + + //IDȷ ȻüĴ + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM4 , 0xC1); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CLKRC , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM2 , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM3 , 0xD0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM7 , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM8 , 0xCE); //0xCE:رԶع 0xCFԶع + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSTART , 0x3F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSIZE , 0x50); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSTRT , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSIZE , 0x78); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HREF , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SCAL0 , 0x0A); + simiic_write_reg(OV7725_DEV_ADD, OV7725_AWB_Ctrl0 , 0xE0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSPAuto , 0xff); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl2 , 0x0C); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl3 , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl4 , 0x00); + + if(OV7725_W == 80) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x14); + else if(OV7725_W == 160) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x28); + else if(OV7725_W == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x3c); + else if(OV7725_W == 320) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x50); + + if(OV7725_H == 60) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x1E); + else if(OV7725_H == 120) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x3c); + else if(OV7725_H == 180) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x5a); + else if(OV7725_H == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x78); + + simiic_write_reg(OV7725_DEV_ADD, OV7725_REG28 , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCH , 0x10); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCL , 0x1F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM1 , 0x0c); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM2 , 0x16); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM3 , 0x2a); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM4 , 0x4e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM5 , 0x61); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM6 , 0x6f); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM7 , 0x7b); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM8 , 0x86); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM9 , 0x8e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM10 , 0x97); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM11 , 0xa4); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM12 , 0xaf); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM13 , 0xc5); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM14 , 0xd7); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM15 , 0xe8); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SLOP , 0x20); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_RADI , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEF , 0x13); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_XC , 0x08); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFB , 0x14); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFR , 0x17); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_CTR , 0x05); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDBase , 0x99); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDMStep , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SDE , 0x04); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BRIGHT , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CNST , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SIGN , 0x06); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ0 , 0x11); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ1 , 0x02); + + + simiic_delay_set(SIMIIC_DELAY_TIME);//޸ΪĬϵ20 + return 1; + + +} + + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷɼʼ(ڲʹãû) +// @param NULL +// @return void +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +void ov7725_port_init(void) +{ + uint8 i; + camera_type = 3;//ͷ + + //ͷɼʼ + //ʼ + for(i=0; i<8; i++) + { + gpio_init((PIN_enum)(OV7725_DATA_PIN+i), GPI, 0, PULLUP); + } + eru_dma_init(OV7725_DMA_CH, GET_PORT_IN_ADDR(OV7725_DATA_PIN), image_bin[0], OV7725_PCLK_PIN, FALLING, OV7725_DMA_NUM); + eru_init(OV7725_VSYNC_PIN, FALLING); //ʼжϣΪ½شж + +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷʼ(֮úжϺɲɼͼ) +// @param NULL +// @return 0 +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_init(void) +{ + simiic_init(); + ov7725_reg_init(); //ͷĴ + ov7725_port_init(); //ͷжżDMA + return 0; +} + + + + +uint8 ov7725_finish_flag = 0; +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбeruGPIOжϣжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_vsync(void) +{ + CLEAR_GPIO_FLAG(OV7725_VSYNC_PIN); + + if(!ov7725_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ + { + DMA_SET_DESTINATION(OV7725_DMA_CH, image_bin[0]); + dma_start(OV7725_DMA_CH); + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷDMAж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбdmaжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_dma(void) +{ + CLEAR_DMA_FLAG(OV7725_DMA_CH); + ov7725_finish_flag = 1; + dma_stop(OV7725_DMA_CH); +} + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷݽѹ +// @param *data1 Դַ +// @param *data2 Ŀĵַ +// @return void +// @since v1.0 +// Sample usage: Image_Decompression(da1,dat2[0]);//һάdat1ݽѹάdat2. +//------------------------------------------------------------------------------------------------------------------- +void image_decompression(uint8 *data1,uint8 *data2) +{ + uint8 temp[2] = {0,255}; + uint16 lenth = OV7725_SIZE; + uint8 i = 8; + + + while(lenth--) + { + i = 8; + while(i--) + { + *data2++ = temp[(*data1 >> i) & 0x01]; + } + data1++; + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷδѹͼλ鿴ͼ +// @param *imgaddr ѹͼݵַ +// @param *imgsize ͼС(ֱдOV7725_SIZE) +// @return void +// @since v1.0 +// Sample usage: øúǰȳʼuart2 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_sendimg_7725(UARTN_enum uartn) +{ + uart_putchar(uartn, 0x00);uart_putchar(uartn, 0xff);uart_putchar(uartn, 0x01);uart_putchar(uartn, 0x01);//ĸֽ + uart_putbuff(uartn, image_bin[0], OV7725_SIZE); //ٷͼ +} + + + + diff --git a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h new file mode 100644 index 0000000..e513250 --- /dev/null +++ b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h @@ -0,0 +1,243 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + + +#ifndef _SEEKFREE_7725_h +#define _SEEKFREE_7725_h + +#include "common.h" +#include "IfxDma_cfg.h" +#include "zf_uart.h" + + +//ͷID +#define OV7725_ID 0x21 + +//ͷĴ +#define OV7725_GAIN 0x00 +#define OV7725_BLUE 0x01 +#define OV7725_RED 0x02 +#define OV7725_GREEN 0x03 +#define OV7725_BAVG 0x05 +#define OV7725_GAVG 0x06 +#define OV7725_RAVG 0x07 +#define OV7725_AECH 0x08 +#define OV7725_COM2 0x09 +#define OV7725_PID 0x0A +#define OV7725_VER 0x0B +#define OV7725_COM3 0x0C +#define OV7725_COM4 0x0D +#define OV7725_COM5 0x0E +#define OV7725_COM6 0x0F +#define OV7725_AEC 0x10 +#define OV7725_CLKRC 0x11 +#define OV7725_COM7 0x12 +#define OV7725_COM8 0x13 +#define OV7725_COM9 0x14 +#define OV7725_COM10 0x15 +#define OV7725_REG16 0x16 +#define OV7725_HSTART 0x17 +#define OV7725_HSIZE 0x18 +#define OV7725_VSTRT 0x19 +#define OV7725_VSIZE 0x1A +#define OV7725_PSHFT 0x1B +#define OV7725_MIDH 0x1C +#define OV7725_MIDL 0x1D +#define OV7725_LAEC 0x1F +#define OV7725_COM11 0x20 +#define OV7725_BDBase 0x22 +#define OV7725_BDMStep 0x23 +#define OV7725_AEW 0x24 +#define OV7725_AEB 0x25 +#define OV7725_VPT 0x26 +#define OV7725_REG28 0x28 +#define OV7725_HOutSize 0x29 +#define OV7725_EXHCH 0x2A +#define OV7725_EXHCL 0x2B +#define OV7725_VOutSize 0x2C +#define OV7725_ADVFL 0x2D +#define OV7725_ADVFH 0x2E +#define OV7725_YAVE 0x2F +#define OV7725_LumHTh 0x30 +#define OV7725_LumLTh 0x31 +#define OV7725_HREF 0x32 +#define OV7725_DM_LNL 0x33 +#define OV7725_DM_LNH 0x34 +#define OV7725_ADoff_B 0x35 +#define OV7725_ADoff_R 0x36 +#define OV7725_ADoff_Gb 0x37 +#define OV7725_ADoff_Gr 0x38 +#define OV7725_Off_B 0x39 +#define OV7725_Off_R 0x3A +#define OV7725_Off_Gb 0x3B +#define OV7725_Off_Gr 0x3C +#define OV7725_COM12 0x3D +#define OV7725_COM13 0x3E +#define OV7725_COM14 0x3F +#define OV7725_COM16 0x41 +#define OV7725_TGT_B 0x42 +#define OV7725_TGT_R 0x43 +#define OV7725_TGT_Gb 0x44 +#define OV7725_TGT_Gr 0x45 +#define OV7725_LC_CTR 0x46 +#define OV7725_LC_XC 0x47 +#define OV7725_LC_YC 0x48 +#define OV7725_LC_COEF 0x49 +#define OV7725_LC_RADI 0x4A +#define OV7725_LC_COEFB 0x4B +#define OV7725_LC_COEFR 0x4C +#define OV7725_FixGain 0x4D +#define OV7725_AREF1 0x4F +#define OV7725_AREF6 0x54 +#define OV7725_UFix 0x60 +#define OV7725_VFix 0x61 +#define OV7725_AWBb_blk 0x62 +#define OV7725_AWB_Ctrl0 0x63 +#define OV7725_DSP_Ctrl1 0x64 +#define OV7725_DSP_Ctrl2 0x65 +#define OV7725_DSP_Ctrl3 0x66 +#define OV7725_DSP_Ctrl4 0x67 +#define OV7725_AWB_bias 0x68 +#define OV7725_AWBCtrl1 0x69 +#define OV7725_AWBCtrl2 0x6A +#define OV7725_AWBCtrl3 0x6B +#define OV7725_AWBCtrl4 0x6C +#define OV7725_AWBCtrl5 0x6D +#define OV7725_AWBCtrl6 0x6E +#define OV7725_AWBCtrl7 0x6F +#define OV7725_AWBCtrl8 0x70 +#define OV7725_AWBCtrl9 0x71 +#define OV7725_AWBCtrl10 0x72 +#define OV7725_AWBCtrl11 0x73 +#define OV7725_AWBCtrl12 0x74 +#define OV7725_AWBCtrl13 0x75 +#define OV7725_AWBCtrl14 0x76 +#define OV7725_AWBCtrl15 0x77 +#define OV7725_AWBCtrl16 0x78 +#define OV7725_AWBCtrl17 0x79 +#define OV7725_AWBCtrl18 0x7A +#define OV7725_AWBCtrl19 0x7B +#define OV7725_AWBCtrl20 0x7C +#define OV7725_AWBCtrl21 0x7D +#define OV7725_GAM1 0x7E +#define OV7725_GAM2 0x7F +#define OV7725_GAM3 0x80 +#define OV7725_GAM4 0x81 +#define OV7725_GAM5 0x82 +#define OV7725_GAM6 0x83 +#define OV7725_GAM7 0x84 +#define OV7725_GAM8 0x85 +#define OV7725_GAM9 0x86 +#define OV7725_GAM10 0x87 +#define OV7725_GAM11 0x88 +#define OV7725_GAM12 0x89 +#define OV7725_GAM13 0x8A +#define OV7725_GAM14 0x8B +#define OV7725_GAM15 0x8C +#define OV7725_SLOP 0x8D +#define OV7725_DNSTh 0x8E +#define OV7725_EDGE0 0x8F +#define OV7725_EDGE1 0x90 +#define OV7725_DNSOff 0x91 +#define OV7725_EDGE2 0x92 +#define OV7725_EDGE3 0x93 +#define OV7725_MTX1 0x94 +#define OV7725_MTX2 0x95 +#define OV7725_MTX3 0x96 +#define OV7725_MTX4 0x97 +#define OV7725_MTX5 0x98 +#define OV7725_MTX6 0x99 +#define OV7725_MTX_Ctrl 0x9A +#define OV7725_BRIGHT 0x9B +#define OV7725_CNST 0x9C +#define OV7725_UVADJ0 0x9E +#define OV7725_UVADJ1 0x9F +#define OV7725_SCAL0 0xA0 +#define OV7725_SCAL1 0xA1 +#define OV7725_SCAL2 0xA2 +#define OV7725_SDE 0xA6 +#define OV7725_USAT 0xA7 +#define OV7725_VSAT 0xA8 +#define OV7725_HUECOS 0xA9 +#define OV7725_HUESIN 0xAA +#define OV7725_SIGN 0xAB +#define OV7725_DSPAuto 0xAC + + +#define OV7725_DEV_ADD 0x42>>1 + + +//ͷ +#define OV7725_W 160 //ͷͼ ò 80 160 240 320 +#define OV7725_H 120 //ͷͼ߶ ò 60 120 180 240 +#define OV7725_SIZE (OV7725_W * OV7725_H/8 ) //ͼռÿռС +#define OV7725_DMA_NUM (OV7725_SIZE) //һͼDMAɼ + + +//-------------------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------------------- +#define OV7725_VSYNC_PIN ERU_CH3_REQ6_P02_0 //ж ѡΧοERU_PIN_enumö ѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DATA_PIN P00_0 //D0 D0ΪP00_0 ôD1ʹõΪP00_1 + //òP00_0P02_0P15_0Ϊ + +#define OV7725_PCLK_PIN ERU_CH2_REQ14_P02_1 //ʱ ѡΧοERU_PIN_enumö 볡жѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ + //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 + + + +extern uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +extern uint8 image_dec[OV7725_H][OV7725_W]; //ͼѹ + +extern uint8 ov7725_finish_flag; //ͼɼɱ־λ + + +// +uint8 ov7725_init(void); +void ov7725_vsync(void); +void ov7725_dma(void); +void image_decompression(uint8 *data1,uint8 *data2); +void seekfree_sendimg_7725(UARTN_enum uartn); + + + +#endif + + + diff --git a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c index 095f9e3..5d167c9 100644 --- a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c +++ b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c @@ -68,6 +68,7 @@ void icm20602_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void icm20602_init(void) { + simiic_init(); systick_delay_ms(STM0, 10); //ϵʱ // diff --git a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c index 196fd57..f56a41a 100644 --- a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c +++ b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c @@ -50,7 +50,7 @@ uint8 IIC_num; // -static uint16 simiic_delay_time=100; //ICMȴӦΪ100 +static uint16 simiic_delay_time = SIMIIC_DELAY_TIME; //ICMȴӦΪ20 //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h index 293a02a..6a9c1e3 100644 --- a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h +++ b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h @@ -34,8 +34,12 @@ -#define SEEKFREE_SCL P13_0 //SCL ΪIO -#define SEEKFREE_SDA P13_1 //SDA ΪIO +#define SEEKFREE_SCL P02_3 //SCL ΪIO +#define SEEKFREE_SDA P02_2 //SDA ΪIO + + +#define SIMIIC_DELAY_TIME 20 + typedef enum IIC //DACģ { diff --git a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c index 0f0c23a..5deb7d3 100644 --- a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c +++ b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c @@ -65,6 +65,7 @@ void l3g4200d_self_check(void) //------------------------------------------------------------------------------------------------------------------- void l3g4200d_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); l3g4200d_self_check(); diff --git a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c index c200427..8a5eec4 100644 --- a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c +++ b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c @@ -68,6 +68,7 @@ void mma8451_self_check(void) //------------------------------------------------------------------------------------------------------------------- uint8 mma845x_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); mma8451_self_check(); diff --git a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c index 0317aa0..686550d 100644 --- a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c +++ b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c @@ -71,6 +71,7 @@ void mpu6050_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void mpu6050_init(void) { + simiic_init(); systick_delay_ms(STM0, 100); //ϵʱ mpu6050_self1_check(); diff --git a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c index 014b435..05f181f 100644 --- a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c +++ b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c @@ -38,7 +38,6 @@ #include "zf_gpio.h" #include "zf_eru.h" #include "zf_eru_dma.h" -#include "stdio.h" #include "SEEKFREE_MT9V03X.h" @@ -49,6 +48,8 @@ uint8 receive[3]; uint8 receive_num = 0; vuint8 uart_receive_flag; +uint8 link_list_num; + //Ҫõͷ int16 MT9V03X_CFG[CONFIG_FINISH][2]= { @@ -305,7 +306,7 @@ void mt9v03x_init(void) gpio_init((PIN_enum)(MT9V03X_DATA_PIN+i), GPI, 0, PULLUP); } - eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W); + link_list_num = eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W*MT9V03X_H); eru_init(MT9V03X_VSYNC_PIN, FALLING); //ʼжϣΪ½شж restoreInterrupts(interrupt_state); @@ -313,7 +314,6 @@ void mt9v03x_init(void) uint8 mt9v03x_finish_flag = 0; //һͼɼɱ־λ -uint8 now_col; //ǰڲɼ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03Xͷж // @param NULL @@ -324,16 +324,15 @@ uint8 now_col; // void mt9v03x_vsync(void) { CLEAR_GPIO_FLAG(MT9V03X_VSYNC_PIN); - now_col = 0; + if(!mt9v03x_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ { - DMA_SET_DESTINATION(MT9V03X_DMA_CH, (void *)&mt9v03x_image[0]); dma_start(MT9V03X_DMA_CH); } } - +uint8 mt9v03x_dma_int_num; //ǰDMAжϴ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03XͷDMAж // @param NULL @@ -344,16 +343,15 @@ void mt9v03x_vsync(void) void mt9v03x_dma(void) { CLEAR_DMA_FLAG(MT9V03X_DMA_CH); + mt9v03x_dma_int_num++; - now_col++; - - if(MT9V03X_H > now_col) - { - dma_start(MT9V03X_DMA_CH); - } - else + if(mt9v03x_dma_int_num >= link_list_num) { + //ɼ + mt9v03x_dma_int_num = 0; mt9v03x_finish_flag = 1;//һͼӲɼʼɼʱ3.8MS(50FPS188*120ֱ) + dma_stop(MT9V03X_DMA_CH); + } } diff --git a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h index a29edd2..0c8a785 100644 --- a/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h +++ b/Example/5-UART_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h @@ -63,9 +63,7 @@ //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ #define MT9V03X_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ - //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 - - + //ͷö typedef enum { diff --git a/Example/5-UART_Demo/USER/isr.c b/Example/5-UART_Demo/USER/isr.c index 15666f2..c6376b0 100644 --- a/Example/5-UART_Demo/USER/isr.c +++ b/Example/5-UART_Demo/USER/isr.c @@ -98,7 +98,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) if(GET_GPIO_FLAG(ERU_CH3_REQ6_P02_0))//ͨ3ж { CLEAR_GPIO_FLAG(ERU_CH3_REQ6_P02_0); - if(1 == camera_type)mt9v03x_vsync(); + if (1 == camera_type) mt9v03x_vsync(); + else if (3 == camera_type) ov7725_vsync(); } if(GET_GPIO_FLAG(ERU_CH7_REQ16_P15_1))//ͨ7ж @@ -113,7 +114,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) IFX_INTERRUPT(dma_ch5_isr, ERU_DMA_INT_SERVICE, ERU_DMA_INT_PRIO) { - if(1 == camera_type) mt9v03x_dma(); + if (1 == camera_type) mt9v03x_dma(); + else if (3 == camera_type) ov7725_dma(); } diff --git a/Example/6-Printf_Demo/Libraries/doc/version.txt b/Example/6-Printf_Demo/Libraries/doc/version.txt index b85cd50..a42bc58 100644 --- a/Example/6-Printf_Demo/Libraries/doc/version.txt +++ b/Example/6-Printf_Demo/Libraries/doc/version.txt @@ -1,9 +1,17 @@ V1.0.0 - ʼ汾 + ʼ汾 V1.0.1 ͷijжϽ޸ģжϱ־λΪ0Ųɼһͼ񣬱ַʳͻ ޸SPIʼеĴ˹̶SPI2ַ ޸STM޷ʹSTM1 - ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ \ No newline at end of file + ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ + +V1.0.2 + ޸ģIICĬʱʱΪ20 + ҪرעP20_2DzģֻĹ ע + ͷɼDMAΪlink䣬Դ󽵵DMAжϴ + ޸ĬϵIICŶ + 6050 ҪõIICģ飬ڳʼĬϵģIICʼ + С \ No newline at end of file diff --git a/Example/6-Printf_Demo/Libraries/seekfree_libraries/common/common.c b/Example/6-Printf_Demo/Libraries/seekfree_libraries/common/common.c index 0460d15..ac42b19 100644 --- a/Example/6-Printf_Demo/Libraries/seekfree_libraries/common/common.c +++ b/Example/6-Printf_Demo/Libraries/seekfree_libraries/common/common.c @@ -22,7 +22,7 @@ #include "SysSe/Bsp/Bsp.h" #include "common.h" -uint8 camera_type; +uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С diff --git a/Example/6-Printf_Demo/Libraries/seekfree_libraries/common/common.h b/Example/6-Printf_Demo/Libraries/seekfree_libraries/common/common.h index fe7ec63..13d03cd 100644 --- a/Example/6-Printf_Demo/Libraries/seekfree_libraries/common/common.h +++ b/Example/6-Printf_Demo/Libraries/seekfree_libraries/common/common.h @@ -111,7 +111,7 @@ typedef enum //ö #include -extern uint8 camera_type; +extern uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С void get_clk(void); diff --git a/Example/6-Printf_Demo/Libraries/seekfree_libraries/headfile.h b/Example/6-Printf_Demo/Libraries/seekfree_libraries/headfile.h index 0e8024f..e11bd83 100644 --- a/Example/6-Printf_Demo/Libraries/seekfree_libraries/headfile.h +++ b/Example/6-Printf_Demo/Libraries/seekfree_libraries/headfile.h @@ -62,6 +62,7 @@ #include "SEEKFREE_L3G4200D.h" #include "SEEKFREE_WIRELESS.h" #include "SEEKFREE_IPS200_PARALLEL8.h" +#include "SEEKFREE_7725.h" #endif diff --git a/Example/6-Printf_Demo/Libraries/seekfree_libraries/zf_eru_dma.c b/Example/6-Printf_Demo/Libraries/seekfree_libraries/zf_eru_dma.c index f7aab10..86c0158 100644 --- a/Example/6-Printf_Demo/Libraries/seekfree_libraries/zf_eru_dma.c +++ b/Example/6-Printf_Demo/Libraries/seekfree_libraries/zf_eru_dma.c @@ -21,9 +21,18 @@ #include "IfxDma_Dma.h" #include "IfxScuEru.h" #include "isr_config.h" +#include "zf_assert.h" #include "zf_eru_dma.h" +typedef struct +{ + Ifx_DMA_CH IFX_ALIGN(256) linked_list[8];//DMA + IfxDma_Dma_Channel channel; //DMAͨ +}DMA_LINK; + + +DMA_LINK dma_link_list; //------------------------------------------------------------------------------------------------------------------- // @brief erudmaʼ @@ -36,7 +45,7 @@ // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) { IfxDma_Dma_Channel dmaChn; //eruDMAͨ eruļeruȼΪͨ @@ -51,27 +60,85 @@ void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destinatio IfxDma_Dma_ChannelConfig cfg; IfxDma_Dma_initChannelConfig(&cfg, &dma); - cfg.transferCount = dma_count; + uint8 list_num, i; + uint16 single_channel_dma_count; + + ZF_ASSERT(!(dma_count%8));//Ϊ8ı + + + list_num = 1; + single_channel_dma_count = dma_count / list_num; + if(16384 < single_channel_dma_count) + { + while(TRUE) + { + single_channel_dma_count = dma_count / list_num; + if((single_channel_dma_count <= 16384) && !(dma_count % list_num)) + { + break; + } + list_num++; + if(list_num > 8) ZF_ASSERT(FALSE); + } + } + + + if(1 == list_num) + { + cfg.shadowControl = IfxDma_ChannelShadow_none; + cfg.operationMode = IfxDma_ChannelOperationMode_single; + cfg.shadowAddress = 0; + } + else + { + cfg.shadowControl = IfxDma_ChannelShadow_linkedList; + cfg.operationMode = IfxDma_ChannelOperationMode_continuous; + cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[1]); + } + cfg.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest; cfg.moveSize = IfxDma_ChannelMoveSize_8bit; + cfg.busPriority = IfxDma_ChannelBusPriority_high; - cfg.busPriority = IfxDma_ChannelBusPriority_high; - - cfg.sourceAddress = (unsigned)(source_addr); + cfg.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), source_addr); cfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_none; cfg.sourceCircularBufferEnabled = TRUE; - cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); cfg.destinationAddressIncrementStep = IfxDma_ChannelIncrementStep_1; - cfg.operationMode = IfxDma_ChannelOperationMode_single; - cfg.channelId = (IfxDma_ChannelId)dma_ch; - cfg.hardwareRequestEnabled = TRUE; - cfg.channelInterruptEnabled = TRUE; + cfg.channelId = (IfxDma_ChannelId)dma_ch; + cfg.hardwareRequestEnabled = FALSE; + cfg.channelInterruptEnabled = TRUE; cfg.channelInterruptPriority = ERU_DMA_INT_PRIO; cfg.channelInterruptTypeOfService = (IfxSrc_Tos)ERU_DMA_INT_SERVICE; + + + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); + + cfg.transferCount = single_channel_dma_count; + IfxDma_Dma_initChannel(&dmaChn, &cfg); + + if(1 < list_num) + { + i = 0; + while(i < list_num) + { + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr + single_channel_dma_count * i); + if(i == (list_num - 1)) cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[0]); + else cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[i+1]); + cfg.transferCount = single_channel_dma_count; + + IfxDma_Dma_initLinkedListEntry((void *)&dma_link_list.linked_list[i], &cfg); + i++; + } + } + + + IfxDma_Dma_getSrcPointer(&dma_link_list.channel)->B.CLRR = 1; + + return list_num; } diff --git a/Example/6-Printf_Demo/Libraries/seekfree_libraries/zf_eru_dma.h b/Example/6-Printf_Demo/Libraries/seekfree_libraries/zf_eru_dma.h index 50667ad..faef169 100644 --- a/Example/6-Printf_Demo/Libraries/seekfree_libraries/zf_eru_dma.h +++ b/Example/6-Printf_Demo/Libraries/seekfree_libraries/zf_eru_dma.h @@ -29,9 +29,9 @@ #define CLEAR_DMA_FLAG(dma_ch) IfxDma_clearChannelInterrupt(&MODULE_DMA, dma_ch); -#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)destination_addr) +#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr)) -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); void dma_stop(IfxDma_ChannelId dma_ch); void dma_start(IfxDma_ChannelId dma_ch); diff --git a/Example/6-Printf_Demo/Libraries/seekfree_libraries/zf_gpio.c b/Example/6-Printf_Demo/Libraries/seekfree_libraries/zf_gpio.c index 3c937cf..1d2466c 100644 --- a/Example/6-Printf_Demo/Libraries/seekfree_libraries/zf_gpio.c +++ b/Example/6-Printf_Demo/Libraries/seekfree_libraries/zf_gpio.c @@ -60,6 +60,7 @@ Ifx_P* get_port(PIN_enum pin) // @param pinmode ãòzf_gpio.hļGPIOMODE_enumöֵȷ // @return void // Sample usage: gpio_init(P00_0, GPO, 1, PUSHPULL);//P00_0ʼΪGPIOܡģʽߵƽ +// @note ҪرעP20_2DzģֻĹ //------------------------------------------------------------------------------------------------------------------- void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinmode) { diff --git a/Example/6-Printf_Demo/Libraries/seekfree_libraries/zf_gpio.h b/Example/6-Printf_Demo/Libraries/seekfree_libraries/zf_gpio.h index cfbd666..e3d144f 100644 --- a/Example/6-Printf_Demo/Libraries/seekfree_libraries/zf_gpio.h +++ b/Example/6-Printf_Demo/Libraries/seekfree_libraries/zf_gpio.h @@ -38,6 +38,15 @@ typedef enum // ö #define GET_PORT_IN_ADDR(pin) (uint8 *)(&IfxPort_getAddress((IfxPort_Index)(pin/32))->IN + pin%32/8) + + +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ + + + + //------------------------------------------------------ //ͨGPIO void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinconf); diff --git a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c new file mode 100644 index 0000000..806b8d9 --- /dev/null +++ b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c @@ -0,0 +1,262 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + +#include "IfxDma.h" +#include "IfxScuEru.h" +#include "zf_stm_systick.h" +#include "zf_gpio.h" +#include "zf_eru.h" +#include "zf_eru_dma.h" +#include "SEEKFREE_IIC.h" +#include "SEEKFREE_7725.h" + + + +IFX_ALIGN(4) uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +uint8 image_dec[OV7725_H][OV7725_W]; + +uint8 ov7725_idcode = 0; + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷڲĴʼ(ڲʹãû) +// @param NULL +// @return uint8 01ɹ +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_reg_init(void) +{ + simiic_delay_set(500); + simiic_write_reg ( OV7725_DEV_ADD, OV7725_COM7, 0x80 ); //λͷ + systick_delay_ms(STM0, 50); + ov7725_idcode = simiic_read_reg( OV7725_DEV_ADD, OV7725_VER ,SCCB); + if( ov7725_idcode != OV7725_ID ) return 0; //УͷID + + //IDȷ ȻüĴ + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM4 , 0xC1); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CLKRC , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM2 , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM3 , 0xD0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM7 , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM8 , 0xCE); //0xCE:رԶع 0xCFԶع + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSTART , 0x3F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSIZE , 0x50); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSTRT , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSIZE , 0x78); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HREF , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SCAL0 , 0x0A); + simiic_write_reg(OV7725_DEV_ADD, OV7725_AWB_Ctrl0 , 0xE0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSPAuto , 0xff); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl2 , 0x0C); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl3 , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl4 , 0x00); + + if(OV7725_W == 80) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x14); + else if(OV7725_W == 160) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x28); + else if(OV7725_W == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x3c); + else if(OV7725_W == 320) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x50); + + if(OV7725_H == 60) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x1E); + else if(OV7725_H == 120) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x3c); + else if(OV7725_H == 180) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x5a); + else if(OV7725_H == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x78); + + simiic_write_reg(OV7725_DEV_ADD, OV7725_REG28 , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCH , 0x10); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCL , 0x1F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM1 , 0x0c); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM2 , 0x16); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM3 , 0x2a); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM4 , 0x4e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM5 , 0x61); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM6 , 0x6f); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM7 , 0x7b); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM8 , 0x86); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM9 , 0x8e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM10 , 0x97); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM11 , 0xa4); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM12 , 0xaf); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM13 , 0xc5); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM14 , 0xd7); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM15 , 0xe8); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SLOP , 0x20); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_RADI , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEF , 0x13); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_XC , 0x08); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFB , 0x14); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFR , 0x17); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_CTR , 0x05); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDBase , 0x99); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDMStep , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SDE , 0x04); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BRIGHT , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CNST , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SIGN , 0x06); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ0 , 0x11); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ1 , 0x02); + + + simiic_delay_set(SIMIIC_DELAY_TIME);//޸ΪĬϵ20 + return 1; + + +} + + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷɼʼ(ڲʹãû) +// @param NULL +// @return void +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +void ov7725_port_init(void) +{ + uint8 i; + camera_type = 3;//ͷ + + //ͷɼʼ + //ʼ + for(i=0; i<8; i++) + { + gpio_init((PIN_enum)(OV7725_DATA_PIN+i), GPI, 0, PULLUP); + } + eru_dma_init(OV7725_DMA_CH, GET_PORT_IN_ADDR(OV7725_DATA_PIN), image_bin[0], OV7725_PCLK_PIN, FALLING, OV7725_DMA_NUM); + eru_init(OV7725_VSYNC_PIN, FALLING); //ʼжϣΪ½شж + +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷʼ(֮úжϺɲɼͼ) +// @param NULL +// @return 0 +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_init(void) +{ + simiic_init(); + ov7725_reg_init(); //ͷĴ + ov7725_port_init(); //ͷжżDMA + return 0; +} + + + + +uint8 ov7725_finish_flag = 0; +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбeruGPIOжϣжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_vsync(void) +{ + CLEAR_GPIO_FLAG(OV7725_VSYNC_PIN); + + if(!ov7725_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ + { + DMA_SET_DESTINATION(OV7725_DMA_CH, image_bin[0]); + dma_start(OV7725_DMA_CH); + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷDMAж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбdmaжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_dma(void) +{ + CLEAR_DMA_FLAG(OV7725_DMA_CH); + ov7725_finish_flag = 1; + dma_stop(OV7725_DMA_CH); +} + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷݽѹ +// @param *data1 Դַ +// @param *data2 Ŀĵַ +// @return void +// @since v1.0 +// Sample usage: Image_Decompression(da1,dat2[0]);//һάdat1ݽѹάdat2. +//------------------------------------------------------------------------------------------------------------------- +void image_decompression(uint8 *data1,uint8 *data2) +{ + uint8 temp[2] = {0,255}; + uint16 lenth = OV7725_SIZE; + uint8 i = 8; + + + while(lenth--) + { + i = 8; + while(i--) + { + *data2++ = temp[(*data1 >> i) & 0x01]; + } + data1++; + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷδѹͼλ鿴ͼ +// @param *imgaddr ѹͼݵַ +// @param *imgsize ͼС(ֱдOV7725_SIZE) +// @return void +// @since v1.0 +// Sample usage: øúǰȳʼuart2 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_sendimg_7725(UARTN_enum uartn) +{ + uart_putchar(uartn, 0x00);uart_putchar(uartn, 0xff);uart_putchar(uartn, 0x01);uart_putchar(uartn, 0x01);//ĸֽ + uart_putbuff(uartn, image_bin[0], OV7725_SIZE); //ٷͼ +} + + + + diff --git a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h new file mode 100644 index 0000000..e513250 --- /dev/null +++ b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h @@ -0,0 +1,243 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + + +#ifndef _SEEKFREE_7725_h +#define _SEEKFREE_7725_h + +#include "common.h" +#include "IfxDma_cfg.h" +#include "zf_uart.h" + + +//ͷID +#define OV7725_ID 0x21 + +//ͷĴ +#define OV7725_GAIN 0x00 +#define OV7725_BLUE 0x01 +#define OV7725_RED 0x02 +#define OV7725_GREEN 0x03 +#define OV7725_BAVG 0x05 +#define OV7725_GAVG 0x06 +#define OV7725_RAVG 0x07 +#define OV7725_AECH 0x08 +#define OV7725_COM2 0x09 +#define OV7725_PID 0x0A +#define OV7725_VER 0x0B +#define OV7725_COM3 0x0C +#define OV7725_COM4 0x0D +#define OV7725_COM5 0x0E +#define OV7725_COM6 0x0F +#define OV7725_AEC 0x10 +#define OV7725_CLKRC 0x11 +#define OV7725_COM7 0x12 +#define OV7725_COM8 0x13 +#define OV7725_COM9 0x14 +#define OV7725_COM10 0x15 +#define OV7725_REG16 0x16 +#define OV7725_HSTART 0x17 +#define OV7725_HSIZE 0x18 +#define OV7725_VSTRT 0x19 +#define OV7725_VSIZE 0x1A +#define OV7725_PSHFT 0x1B +#define OV7725_MIDH 0x1C +#define OV7725_MIDL 0x1D +#define OV7725_LAEC 0x1F +#define OV7725_COM11 0x20 +#define OV7725_BDBase 0x22 +#define OV7725_BDMStep 0x23 +#define OV7725_AEW 0x24 +#define OV7725_AEB 0x25 +#define OV7725_VPT 0x26 +#define OV7725_REG28 0x28 +#define OV7725_HOutSize 0x29 +#define OV7725_EXHCH 0x2A +#define OV7725_EXHCL 0x2B +#define OV7725_VOutSize 0x2C +#define OV7725_ADVFL 0x2D +#define OV7725_ADVFH 0x2E +#define OV7725_YAVE 0x2F +#define OV7725_LumHTh 0x30 +#define OV7725_LumLTh 0x31 +#define OV7725_HREF 0x32 +#define OV7725_DM_LNL 0x33 +#define OV7725_DM_LNH 0x34 +#define OV7725_ADoff_B 0x35 +#define OV7725_ADoff_R 0x36 +#define OV7725_ADoff_Gb 0x37 +#define OV7725_ADoff_Gr 0x38 +#define OV7725_Off_B 0x39 +#define OV7725_Off_R 0x3A +#define OV7725_Off_Gb 0x3B +#define OV7725_Off_Gr 0x3C +#define OV7725_COM12 0x3D +#define OV7725_COM13 0x3E +#define OV7725_COM14 0x3F +#define OV7725_COM16 0x41 +#define OV7725_TGT_B 0x42 +#define OV7725_TGT_R 0x43 +#define OV7725_TGT_Gb 0x44 +#define OV7725_TGT_Gr 0x45 +#define OV7725_LC_CTR 0x46 +#define OV7725_LC_XC 0x47 +#define OV7725_LC_YC 0x48 +#define OV7725_LC_COEF 0x49 +#define OV7725_LC_RADI 0x4A +#define OV7725_LC_COEFB 0x4B +#define OV7725_LC_COEFR 0x4C +#define OV7725_FixGain 0x4D +#define OV7725_AREF1 0x4F +#define OV7725_AREF6 0x54 +#define OV7725_UFix 0x60 +#define OV7725_VFix 0x61 +#define OV7725_AWBb_blk 0x62 +#define OV7725_AWB_Ctrl0 0x63 +#define OV7725_DSP_Ctrl1 0x64 +#define OV7725_DSP_Ctrl2 0x65 +#define OV7725_DSP_Ctrl3 0x66 +#define OV7725_DSP_Ctrl4 0x67 +#define OV7725_AWB_bias 0x68 +#define OV7725_AWBCtrl1 0x69 +#define OV7725_AWBCtrl2 0x6A +#define OV7725_AWBCtrl3 0x6B +#define OV7725_AWBCtrl4 0x6C +#define OV7725_AWBCtrl5 0x6D +#define OV7725_AWBCtrl6 0x6E +#define OV7725_AWBCtrl7 0x6F +#define OV7725_AWBCtrl8 0x70 +#define OV7725_AWBCtrl9 0x71 +#define OV7725_AWBCtrl10 0x72 +#define OV7725_AWBCtrl11 0x73 +#define OV7725_AWBCtrl12 0x74 +#define OV7725_AWBCtrl13 0x75 +#define OV7725_AWBCtrl14 0x76 +#define OV7725_AWBCtrl15 0x77 +#define OV7725_AWBCtrl16 0x78 +#define OV7725_AWBCtrl17 0x79 +#define OV7725_AWBCtrl18 0x7A +#define OV7725_AWBCtrl19 0x7B +#define OV7725_AWBCtrl20 0x7C +#define OV7725_AWBCtrl21 0x7D +#define OV7725_GAM1 0x7E +#define OV7725_GAM2 0x7F +#define OV7725_GAM3 0x80 +#define OV7725_GAM4 0x81 +#define OV7725_GAM5 0x82 +#define OV7725_GAM6 0x83 +#define OV7725_GAM7 0x84 +#define OV7725_GAM8 0x85 +#define OV7725_GAM9 0x86 +#define OV7725_GAM10 0x87 +#define OV7725_GAM11 0x88 +#define OV7725_GAM12 0x89 +#define OV7725_GAM13 0x8A +#define OV7725_GAM14 0x8B +#define OV7725_GAM15 0x8C +#define OV7725_SLOP 0x8D +#define OV7725_DNSTh 0x8E +#define OV7725_EDGE0 0x8F +#define OV7725_EDGE1 0x90 +#define OV7725_DNSOff 0x91 +#define OV7725_EDGE2 0x92 +#define OV7725_EDGE3 0x93 +#define OV7725_MTX1 0x94 +#define OV7725_MTX2 0x95 +#define OV7725_MTX3 0x96 +#define OV7725_MTX4 0x97 +#define OV7725_MTX5 0x98 +#define OV7725_MTX6 0x99 +#define OV7725_MTX_Ctrl 0x9A +#define OV7725_BRIGHT 0x9B +#define OV7725_CNST 0x9C +#define OV7725_UVADJ0 0x9E +#define OV7725_UVADJ1 0x9F +#define OV7725_SCAL0 0xA0 +#define OV7725_SCAL1 0xA1 +#define OV7725_SCAL2 0xA2 +#define OV7725_SDE 0xA6 +#define OV7725_USAT 0xA7 +#define OV7725_VSAT 0xA8 +#define OV7725_HUECOS 0xA9 +#define OV7725_HUESIN 0xAA +#define OV7725_SIGN 0xAB +#define OV7725_DSPAuto 0xAC + + +#define OV7725_DEV_ADD 0x42>>1 + + +//ͷ +#define OV7725_W 160 //ͷͼ ò 80 160 240 320 +#define OV7725_H 120 //ͷͼ߶ ò 60 120 180 240 +#define OV7725_SIZE (OV7725_W * OV7725_H/8 ) //ͼռÿռС +#define OV7725_DMA_NUM (OV7725_SIZE) //һͼDMAɼ + + +//-------------------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------------------- +#define OV7725_VSYNC_PIN ERU_CH3_REQ6_P02_0 //ж ѡΧοERU_PIN_enumö ѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DATA_PIN P00_0 //D0 D0ΪP00_0 ôD1ʹõΪP00_1 + //òP00_0P02_0P15_0Ϊ + +#define OV7725_PCLK_PIN ERU_CH2_REQ14_P02_1 //ʱ ѡΧοERU_PIN_enumö 볡жѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ + //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 + + + +extern uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +extern uint8 image_dec[OV7725_H][OV7725_W]; //ͼѹ + +extern uint8 ov7725_finish_flag; //ͼɼɱ־λ + + +// +uint8 ov7725_init(void); +void ov7725_vsync(void); +void ov7725_dma(void); +void image_decompression(uint8 *data1,uint8 *data2); +void seekfree_sendimg_7725(UARTN_enum uartn); + + + +#endif + + + diff --git a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c index 095f9e3..5d167c9 100644 --- a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c +++ b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c @@ -68,6 +68,7 @@ void icm20602_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void icm20602_init(void) { + simiic_init(); systick_delay_ms(STM0, 10); //ϵʱ // diff --git a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c index 196fd57..f56a41a 100644 --- a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c +++ b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c @@ -50,7 +50,7 @@ uint8 IIC_num; // -static uint16 simiic_delay_time=100; //ICMȴӦΪ100 +static uint16 simiic_delay_time = SIMIIC_DELAY_TIME; //ICMȴӦΪ20 //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h index 293a02a..6a9c1e3 100644 --- a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h +++ b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h @@ -34,8 +34,12 @@ -#define SEEKFREE_SCL P13_0 //SCL ΪIO -#define SEEKFREE_SDA P13_1 //SDA ΪIO +#define SEEKFREE_SCL P02_3 //SCL ΪIO +#define SEEKFREE_SDA P02_2 //SDA ΪIO + + +#define SIMIIC_DELAY_TIME 20 + typedef enum IIC //DACģ { diff --git a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c index 0f0c23a..5deb7d3 100644 --- a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c +++ b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c @@ -65,6 +65,7 @@ void l3g4200d_self_check(void) //------------------------------------------------------------------------------------------------------------------- void l3g4200d_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); l3g4200d_self_check(); diff --git a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c index c200427..8a5eec4 100644 --- a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c +++ b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c @@ -68,6 +68,7 @@ void mma8451_self_check(void) //------------------------------------------------------------------------------------------------------------------- uint8 mma845x_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); mma8451_self_check(); diff --git a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c index 0317aa0..686550d 100644 --- a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c +++ b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c @@ -71,6 +71,7 @@ void mpu6050_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void mpu6050_init(void) { + simiic_init(); systick_delay_ms(STM0, 100); //ϵʱ mpu6050_self1_check(); diff --git a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c index 014b435..05f181f 100644 --- a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c +++ b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c @@ -38,7 +38,6 @@ #include "zf_gpio.h" #include "zf_eru.h" #include "zf_eru_dma.h" -#include "stdio.h" #include "SEEKFREE_MT9V03X.h" @@ -49,6 +48,8 @@ uint8 receive[3]; uint8 receive_num = 0; vuint8 uart_receive_flag; +uint8 link_list_num; + //Ҫõͷ int16 MT9V03X_CFG[CONFIG_FINISH][2]= { @@ -305,7 +306,7 @@ void mt9v03x_init(void) gpio_init((PIN_enum)(MT9V03X_DATA_PIN+i), GPI, 0, PULLUP); } - eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W); + link_list_num = eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W*MT9V03X_H); eru_init(MT9V03X_VSYNC_PIN, FALLING); //ʼжϣΪ½شж restoreInterrupts(interrupt_state); @@ -313,7 +314,6 @@ void mt9v03x_init(void) uint8 mt9v03x_finish_flag = 0; //һͼɼɱ־λ -uint8 now_col; //ǰڲɼ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03Xͷж // @param NULL @@ -324,16 +324,15 @@ uint8 now_col; // void mt9v03x_vsync(void) { CLEAR_GPIO_FLAG(MT9V03X_VSYNC_PIN); - now_col = 0; + if(!mt9v03x_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ { - DMA_SET_DESTINATION(MT9V03X_DMA_CH, (void *)&mt9v03x_image[0]); dma_start(MT9V03X_DMA_CH); } } - +uint8 mt9v03x_dma_int_num; //ǰDMAжϴ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03XͷDMAж // @param NULL @@ -344,16 +343,15 @@ void mt9v03x_vsync(void) void mt9v03x_dma(void) { CLEAR_DMA_FLAG(MT9V03X_DMA_CH); + mt9v03x_dma_int_num++; - now_col++; - - if(MT9V03X_H > now_col) - { - dma_start(MT9V03X_DMA_CH); - } - else + if(mt9v03x_dma_int_num >= link_list_num) { + //ɼ + mt9v03x_dma_int_num = 0; mt9v03x_finish_flag = 1;//һͼӲɼʼɼʱ3.8MS(50FPS188*120ֱ) + dma_stop(MT9V03X_DMA_CH); + } } diff --git a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h index a29edd2..0c8a785 100644 --- a/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h +++ b/Example/6-Printf_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h @@ -63,9 +63,7 @@ //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ #define MT9V03X_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ - //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 - - + //ͷö typedef enum { diff --git a/Example/6-Printf_Demo/USER/isr.c b/Example/6-Printf_Demo/USER/isr.c index 15666f2..c6376b0 100644 --- a/Example/6-Printf_Demo/USER/isr.c +++ b/Example/6-Printf_Demo/USER/isr.c @@ -98,7 +98,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) if(GET_GPIO_FLAG(ERU_CH3_REQ6_P02_0))//ͨ3ж { CLEAR_GPIO_FLAG(ERU_CH3_REQ6_P02_0); - if(1 == camera_type)mt9v03x_vsync(); + if (1 == camera_type) mt9v03x_vsync(); + else if (3 == camera_type) ov7725_vsync(); } if(GET_GPIO_FLAG(ERU_CH7_REQ16_P15_1))//ͨ7ж @@ -113,7 +114,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) IFX_INTERRUPT(dma_ch5_isr, ERU_DMA_INT_SERVICE, ERU_DMA_INT_PRIO) { - if(1 == camera_type) mt9v03x_dma(); + if (1 == camera_type) mt9v03x_dma(); + else if (3 == camera_type) ov7725_dma(); } diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/doc/version.txt b/Example/7-GPIO_Interrupt_Demo/Libraries/doc/version.txt index b85cd50..a42bc58 100644 --- a/Example/7-GPIO_Interrupt_Demo/Libraries/doc/version.txt +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/doc/version.txt @@ -1,9 +1,17 @@ V1.0.0 - ʼ汾 + ʼ汾 V1.0.1 ͷijжϽ޸ģжϱ־λΪ0Ųɼһͼ񣬱ַʳͻ ޸SPIʼеĴ˹̶SPI2ַ ޸STM޷ʹSTM1 - ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ \ No newline at end of file + ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ + +V1.0.2 + ޸ģIICĬʱʱΪ20 + ҪرעP20_2DzģֻĹ ע + ͷɼDMAΪlink䣬Դ󽵵DMAжϴ + ޸ĬϵIICŶ + 6050 ҪõIICģ飬ڳʼĬϵģIICʼ + С \ No newline at end of file diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/common/common.c b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/common/common.c index 0460d15..ac42b19 100644 --- a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/common/common.c +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/common/common.c @@ -22,7 +22,7 @@ #include "SysSe/Bsp/Bsp.h" #include "common.h" -uint8 camera_type; +uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/common/common.h b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/common/common.h index fe7ec63..13d03cd 100644 --- a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/common/common.h +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/common/common.h @@ -111,7 +111,7 @@ typedef enum //ö #include -extern uint8 camera_type; +extern uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С void get_clk(void); diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/headfile.h b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/headfile.h index 0e8024f..e11bd83 100644 --- a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/headfile.h +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/headfile.h @@ -62,6 +62,7 @@ #include "SEEKFREE_L3G4200D.h" #include "SEEKFREE_WIRELESS.h" #include "SEEKFREE_IPS200_PARALLEL8.h" +#include "SEEKFREE_7725.h" #endif diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/zf_eru_dma.c b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/zf_eru_dma.c index f7aab10..86c0158 100644 --- a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/zf_eru_dma.c +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/zf_eru_dma.c @@ -21,9 +21,18 @@ #include "IfxDma_Dma.h" #include "IfxScuEru.h" #include "isr_config.h" +#include "zf_assert.h" #include "zf_eru_dma.h" +typedef struct +{ + Ifx_DMA_CH IFX_ALIGN(256) linked_list[8];//DMA + IfxDma_Dma_Channel channel; //DMAͨ +}DMA_LINK; + + +DMA_LINK dma_link_list; //------------------------------------------------------------------------------------------------------------------- // @brief erudmaʼ @@ -36,7 +45,7 @@ // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) { IfxDma_Dma_Channel dmaChn; //eruDMAͨ eruļeruȼΪͨ @@ -51,27 +60,85 @@ void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destinatio IfxDma_Dma_ChannelConfig cfg; IfxDma_Dma_initChannelConfig(&cfg, &dma); - cfg.transferCount = dma_count; + uint8 list_num, i; + uint16 single_channel_dma_count; + + ZF_ASSERT(!(dma_count%8));//Ϊ8ı + + + list_num = 1; + single_channel_dma_count = dma_count / list_num; + if(16384 < single_channel_dma_count) + { + while(TRUE) + { + single_channel_dma_count = dma_count / list_num; + if((single_channel_dma_count <= 16384) && !(dma_count % list_num)) + { + break; + } + list_num++; + if(list_num > 8) ZF_ASSERT(FALSE); + } + } + + + if(1 == list_num) + { + cfg.shadowControl = IfxDma_ChannelShadow_none; + cfg.operationMode = IfxDma_ChannelOperationMode_single; + cfg.shadowAddress = 0; + } + else + { + cfg.shadowControl = IfxDma_ChannelShadow_linkedList; + cfg.operationMode = IfxDma_ChannelOperationMode_continuous; + cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[1]); + } + cfg.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest; cfg.moveSize = IfxDma_ChannelMoveSize_8bit; + cfg.busPriority = IfxDma_ChannelBusPriority_high; - cfg.busPriority = IfxDma_ChannelBusPriority_high; - - cfg.sourceAddress = (unsigned)(source_addr); + cfg.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), source_addr); cfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_none; cfg.sourceCircularBufferEnabled = TRUE; - cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); cfg.destinationAddressIncrementStep = IfxDma_ChannelIncrementStep_1; - cfg.operationMode = IfxDma_ChannelOperationMode_single; - cfg.channelId = (IfxDma_ChannelId)dma_ch; - cfg.hardwareRequestEnabled = TRUE; - cfg.channelInterruptEnabled = TRUE; + cfg.channelId = (IfxDma_ChannelId)dma_ch; + cfg.hardwareRequestEnabled = FALSE; + cfg.channelInterruptEnabled = TRUE; cfg.channelInterruptPriority = ERU_DMA_INT_PRIO; cfg.channelInterruptTypeOfService = (IfxSrc_Tos)ERU_DMA_INT_SERVICE; + + + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); + + cfg.transferCount = single_channel_dma_count; + IfxDma_Dma_initChannel(&dmaChn, &cfg); + + if(1 < list_num) + { + i = 0; + while(i < list_num) + { + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr + single_channel_dma_count * i); + if(i == (list_num - 1)) cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[0]); + else cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[i+1]); + cfg.transferCount = single_channel_dma_count; + + IfxDma_Dma_initLinkedListEntry((void *)&dma_link_list.linked_list[i], &cfg); + i++; + } + } + + + IfxDma_Dma_getSrcPointer(&dma_link_list.channel)->B.CLRR = 1; + + return list_num; } diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/zf_eru_dma.h b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/zf_eru_dma.h index 50667ad..faef169 100644 --- a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/zf_eru_dma.h +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/zf_eru_dma.h @@ -29,9 +29,9 @@ #define CLEAR_DMA_FLAG(dma_ch) IfxDma_clearChannelInterrupt(&MODULE_DMA, dma_ch); -#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)destination_addr) +#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr)) -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); void dma_stop(IfxDma_ChannelId dma_ch); void dma_start(IfxDma_ChannelId dma_ch); diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/zf_gpio.c b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/zf_gpio.c index 3c937cf..1d2466c 100644 --- a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/zf_gpio.c +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/zf_gpio.c @@ -60,6 +60,7 @@ Ifx_P* get_port(PIN_enum pin) // @param pinmode ãòzf_gpio.hļGPIOMODE_enumöֵȷ // @return void // Sample usage: gpio_init(P00_0, GPO, 1, PUSHPULL);//P00_0ʼΪGPIOܡģʽߵƽ +// @note ҪرעP20_2DzģֻĹ //------------------------------------------------------------------------------------------------------------------- void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinmode) { diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/zf_gpio.h b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/zf_gpio.h index cfbd666..e3d144f 100644 --- a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/zf_gpio.h +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_libraries/zf_gpio.h @@ -38,6 +38,15 @@ typedef enum // ö #define GET_PORT_IN_ADDR(pin) (uint8 *)(&IfxPort_getAddress((IfxPort_Index)(pin/32))->IN + pin%32/8) + + +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ + + + + //------------------------------------------------------ //ͨGPIO void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinconf); diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c new file mode 100644 index 0000000..806b8d9 --- /dev/null +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c @@ -0,0 +1,262 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + +#include "IfxDma.h" +#include "IfxScuEru.h" +#include "zf_stm_systick.h" +#include "zf_gpio.h" +#include "zf_eru.h" +#include "zf_eru_dma.h" +#include "SEEKFREE_IIC.h" +#include "SEEKFREE_7725.h" + + + +IFX_ALIGN(4) uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +uint8 image_dec[OV7725_H][OV7725_W]; + +uint8 ov7725_idcode = 0; + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷڲĴʼ(ڲʹãû) +// @param NULL +// @return uint8 01ɹ +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_reg_init(void) +{ + simiic_delay_set(500); + simiic_write_reg ( OV7725_DEV_ADD, OV7725_COM7, 0x80 ); //λͷ + systick_delay_ms(STM0, 50); + ov7725_idcode = simiic_read_reg( OV7725_DEV_ADD, OV7725_VER ,SCCB); + if( ov7725_idcode != OV7725_ID ) return 0; //УͷID + + //IDȷ ȻüĴ + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM4 , 0xC1); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CLKRC , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM2 , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM3 , 0xD0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM7 , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM8 , 0xCE); //0xCE:رԶع 0xCFԶع + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSTART , 0x3F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSIZE , 0x50); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSTRT , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSIZE , 0x78); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HREF , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SCAL0 , 0x0A); + simiic_write_reg(OV7725_DEV_ADD, OV7725_AWB_Ctrl0 , 0xE0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSPAuto , 0xff); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl2 , 0x0C); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl3 , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl4 , 0x00); + + if(OV7725_W == 80) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x14); + else if(OV7725_W == 160) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x28); + else if(OV7725_W == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x3c); + else if(OV7725_W == 320) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x50); + + if(OV7725_H == 60) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x1E); + else if(OV7725_H == 120) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x3c); + else if(OV7725_H == 180) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x5a); + else if(OV7725_H == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x78); + + simiic_write_reg(OV7725_DEV_ADD, OV7725_REG28 , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCH , 0x10); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCL , 0x1F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM1 , 0x0c); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM2 , 0x16); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM3 , 0x2a); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM4 , 0x4e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM5 , 0x61); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM6 , 0x6f); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM7 , 0x7b); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM8 , 0x86); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM9 , 0x8e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM10 , 0x97); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM11 , 0xa4); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM12 , 0xaf); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM13 , 0xc5); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM14 , 0xd7); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM15 , 0xe8); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SLOP , 0x20); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_RADI , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEF , 0x13); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_XC , 0x08); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFB , 0x14); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFR , 0x17); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_CTR , 0x05); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDBase , 0x99); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDMStep , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SDE , 0x04); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BRIGHT , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CNST , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SIGN , 0x06); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ0 , 0x11); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ1 , 0x02); + + + simiic_delay_set(SIMIIC_DELAY_TIME);//޸ΪĬϵ20 + return 1; + + +} + + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷɼʼ(ڲʹãû) +// @param NULL +// @return void +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +void ov7725_port_init(void) +{ + uint8 i; + camera_type = 3;//ͷ + + //ͷɼʼ + //ʼ + for(i=0; i<8; i++) + { + gpio_init((PIN_enum)(OV7725_DATA_PIN+i), GPI, 0, PULLUP); + } + eru_dma_init(OV7725_DMA_CH, GET_PORT_IN_ADDR(OV7725_DATA_PIN), image_bin[0], OV7725_PCLK_PIN, FALLING, OV7725_DMA_NUM); + eru_init(OV7725_VSYNC_PIN, FALLING); //ʼжϣΪ½شж + +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷʼ(֮úжϺɲɼͼ) +// @param NULL +// @return 0 +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_init(void) +{ + simiic_init(); + ov7725_reg_init(); //ͷĴ + ov7725_port_init(); //ͷжżDMA + return 0; +} + + + + +uint8 ov7725_finish_flag = 0; +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбeruGPIOжϣжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_vsync(void) +{ + CLEAR_GPIO_FLAG(OV7725_VSYNC_PIN); + + if(!ov7725_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ + { + DMA_SET_DESTINATION(OV7725_DMA_CH, image_bin[0]); + dma_start(OV7725_DMA_CH); + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷDMAж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбdmaжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_dma(void) +{ + CLEAR_DMA_FLAG(OV7725_DMA_CH); + ov7725_finish_flag = 1; + dma_stop(OV7725_DMA_CH); +} + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷݽѹ +// @param *data1 Դַ +// @param *data2 Ŀĵַ +// @return void +// @since v1.0 +// Sample usage: Image_Decompression(da1,dat2[0]);//һάdat1ݽѹάdat2. +//------------------------------------------------------------------------------------------------------------------- +void image_decompression(uint8 *data1,uint8 *data2) +{ + uint8 temp[2] = {0,255}; + uint16 lenth = OV7725_SIZE; + uint8 i = 8; + + + while(lenth--) + { + i = 8; + while(i--) + { + *data2++ = temp[(*data1 >> i) & 0x01]; + } + data1++; + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷδѹͼλ鿴ͼ +// @param *imgaddr ѹͼݵַ +// @param *imgsize ͼС(ֱдOV7725_SIZE) +// @return void +// @since v1.0 +// Sample usage: øúǰȳʼuart2 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_sendimg_7725(UARTN_enum uartn) +{ + uart_putchar(uartn, 0x00);uart_putchar(uartn, 0xff);uart_putchar(uartn, 0x01);uart_putchar(uartn, 0x01);//ĸֽ + uart_putbuff(uartn, image_bin[0], OV7725_SIZE); //ٷͼ +} + + + + diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h new file mode 100644 index 0000000..e513250 --- /dev/null +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h @@ -0,0 +1,243 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + + +#ifndef _SEEKFREE_7725_h +#define _SEEKFREE_7725_h + +#include "common.h" +#include "IfxDma_cfg.h" +#include "zf_uart.h" + + +//ͷID +#define OV7725_ID 0x21 + +//ͷĴ +#define OV7725_GAIN 0x00 +#define OV7725_BLUE 0x01 +#define OV7725_RED 0x02 +#define OV7725_GREEN 0x03 +#define OV7725_BAVG 0x05 +#define OV7725_GAVG 0x06 +#define OV7725_RAVG 0x07 +#define OV7725_AECH 0x08 +#define OV7725_COM2 0x09 +#define OV7725_PID 0x0A +#define OV7725_VER 0x0B +#define OV7725_COM3 0x0C +#define OV7725_COM4 0x0D +#define OV7725_COM5 0x0E +#define OV7725_COM6 0x0F +#define OV7725_AEC 0x10 +#define OV7725_CLKRC 0x11 +#define OV7725_COM7 0x12 +#define OV7725_COM8 0x13 +#define OV7725_COM9 0x14 +#define OV7725_COM10 0x15 +#define OV7725_REG16 0x16 +#define OV7725_HSTART 0x17 +#define OV7725_HSIZE 0x18 +#define OV7725_VSTRT 0x19 +#define OV7725_VSIZE 0x1A +#define OV7725_PSHFT 0x1B +#define OV7725_MIDH 0x1C +#define OV7725_MIDL 0x1D +#define OV7725_LAEC 0x1F +#define OV7725_COM11 0x20 +#define OV7725_BDBase 0x22 +#define OV7725_BDMStep 0x23 +#define OV7725_AEW 0x24 +#define OV7725_AEB 0x25 +#define OV7725_VPT 0x26 +#define OV7725_REG28 0x28 +#define OV7725_HOutSize 0x29 +#define OV7725_EXHCH 0x2A +#define OV7725_EXHCL 0x2B +#define OV7725_VOutSize 0x2C +#define OV7725_ADVFL 0x2D +#define OV7725_ADVFH 0x2E +#define OV7725_YAVE 0x2F +#define OV7725_LumHTh 0x30 +#define OV7725_LumLTh 0x31 +#define OV7725_HREF 0x32 +#define OV7725_DM_LNL 0x33 +#define OV7725_DM_LNH 0x34 +#define OV7725_ADoff_B 0x35 +#define OV7725_ADoff_R 0x36 +#define OV7725_ADoff_Gb 0x37 +#define OV7725_ADoff_Gr 0x38 +#define OV7725_Off_B 0x39 +#define OV7725_Off_R 0x3A +#define OV7725_Off_Gb 0x3B +#define OV7725_Off_Gr 0x3C +#define OV7725_COM12 0x3D +#define OV7725_COM13 0x3E +#define OV7725_COM14 0x3F +#define OV7725_COM16 0x41 +#define OV7725_TGT_B 0x42 +#define OV7725_TGT_R 0x43 +#define OV7725_TGT_Gb 0x44 +#define OV7725_TGT_Gr 0x45 +#define OV7725_LC_CTR 0x46 +#define OV7725_LC_XC 0x47 +#define OV7725_LC_YC 0x48 +#define OV7725_LC_COEF 0x49 +#define OV7725_LC_RADI 0x4A +#define OV7725_LC_COEFB 0x4B +#define OV7725_LC_COEFR 0x4C +#define OV7725_FixGain 0x4D +#define OV7725_AREF1 0x4F +#define OV7725_AREF6 0x54 +#define OV7725_UFix 0x60 +#define OV7725_VFix 0x61 +#define OV7725_AWBb_blk 0x62 +#define OV7725_AWB_Ctrl0 0x63 +#define OV7725_DSP_Ctrl1 0x64 +#define OV7725_DSP_Ctrl2 0x65 +#define OV7725_DSP_Ctrl3 0x66 +#define OV7725_DSP_Ctrl4 0x67 +#define OV7725_AWB_bias 0x68 +#define OV7725_AWBCtrl1 0x69 +#define OV7725_AWBCtrl2 0x6A +#define OV7725_AWBCtrl3 0x6B +#define OV7725_AWBCtrl4 0x6C +#define OV7725_AWBCtrl5 0x6D +#define OV7725_AWBCtrl6 0x6E +#define OV7725_AWBCtrl7 0x6F +#define OV7725_AWBCtrl8 0x70 +#define OV7725_AWBCtrl9 0x71 +#define OV7725_AWBCtrl10 0x72 +#define OV7725_AWBCtrl11 0x73 +#define OV7725_AWBCtrl12 0x74 +#define OV7725_AWBCtrl13 0x75 +#define OV7725_AWBCtrl14 0x76 +#define OV7725_AWBCtrl15 0x77 +#define OV7725_AWBCtrl16 0x78 +#define OV7725_AWBCtrl17 0x79 +#define OV7725_AWBCtrl18 0x7A +#define OV7725_AWBCtrl19 0x7B +#define OV7725_AWBCtrl20 0x7C +#define OV7725_AWBCtrl21 0x7D +#define OV7725_GAM1 0x7E +#define OV7725_GAM2 0x7F +#define OV7725_GAM3 0x80 +#define OV7725_GAM4 0x81 +#define OV7725_GAM5 0x82 +#define OV7725_GAM6 0x83 +#define OV7725_GAM7 0x84 +#define OV7725_GAM8 0x85 +#define OV7725_GAM9 0x86 +#define OV7725_GAM10 0x87 +#define OV7725_GAM11 0x88 +#define OV7725_GAM12 0x89 +#define OV7725_GAM13 0x8A +#define OV7725_GAM14 0x8B +#define OV7725_GAM15 0x8C +#define OV7725_SLOP 0x8D +#define OV7725_DNSTh 0x8E +#define OV7725_EDGE0 0x8F +#define OV7725_EDGE1 0x90 +#define OV7725_DNSOff 0x91 +#define OV7725_EDGE2 0x92 +#define OV7725_EDGE3 0x93 +#define OV7725_MTX1 0x94 +#define OV7725_MTX2 0x95 +#define OV7725_MTX3 0x96 +#define OV7725_MTX4 0x97 +#define OV7725_MTX5 0x98 +#define OV7725_MTX6 0x99 +#define OV7725_MTX_Ctrl 0x9A +#define OV7725_BRIGHT 0x9B +#define OV7725_CNST 0x9C +#define OV7725_UVADJ0 0x9E +#define OV7725_UVADJ1 0x9F +#define OV7725_SCAL0 0xA0 +#define OV7725_SCAL1 0xA1 +#define OV7725_SCAL2 0xA2 +#define OV7725_SDE 0xA6 +#define OV7725_USAT 0xA7 +#define OV7725_VSAT 0xA8 +#define OV7725_HUECOS 0xA9 +#define OV7725_HUESIN 0xAA +#define OV7725_SIGN 0xAB +#define OV7725_DSPAuto 0xAC + + +#define OV7725_DEV_ADD 0x42>>1 + + +//ͷ +#define OV7725_W 160 //ͷͼ ò 80 160 240 320 +#define OV7725_H 120 //ͷͼ߶ ò 60 120 180 240 +#define OV7725_SIZE (OV7725_W * OV7725_H/8 ) //ͼռÿռС +#define OV7725_DMA_NUM (OV7725_SIZE) //һͼDMAɼ + + +//-------------------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------------------- +#define OV7725_VSYNC_PIN ERU_CH3_REQ6_P02_0 //ж ѡΧοERU_PIN_enumö ѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DATA_PIN P00_0 //D0 D0ΪP00_0 ôD1ʹõΪP00_1 + //òP00_0P02_0P15_0Ϊ + +#define OV7725_PCLK_PIN ERU_CH2_REQ14_P02_1 //ʱ ѡΧοERU_PIN_enumö 볡жѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ + //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 + + + +extern uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +extern uint8 image_dec[OV7725_H][OV7725_W]; //ͼѹ + +extern uint8 ov7725_finish_flag; //ͼɼɱ־λ + + +// +uint8 ov7725_init(void); +void ov7725_vsync(void); +void ov7725_dma(void); +void image_decompression(uint8 *data1,uint8 *data2); +void seekfree_sendimg_7725(UARTN_enum uartn); + + + +#endif + + + diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c index 095f9e3..5d167c9 100644 --- a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c @@ -68,6 +68,7 @@ void icm20602_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void icm20602_init(void) { + simiic_init(); systick_delay_ms(STM0, 10); //ϵʱ // diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c index 196fd57..f56a41a 100644 --- a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c @@ -50,7 +50,7 @@ uint8 IIC_num; // -static uint16 simiic_delay_time=100; //ICMȴӦΪ100 +static uint16 simiic_delay_time = SIMIIC_DELAY_TIME; //ICMȴӦΪ20 //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h index 293a02a..6a9c1e3 100644 --- a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h @@ -34,8 +34,12 @@ -#define SEEKFREE_SCL P13_0 //SCL ΪIO -#define SEEKFREE_SDA P13_1 //SDA ΪIO +#define SEEKFREE_SCL P02_3 //SCL ΪIO +#define SEEKFREE_SDA P02_2 //SDA ΪIO + + +#define SIMIIC_DELAY_TIME 20 + typedef enum IIC //DACģ { diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c index 0f0c23a..5deb7d3 100644 --- a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c @@ -65,6 +65,7 @@ void l3g4200d_self_check(void) //------------------------------------------------------------------------------------------------------------------- void l3g4200d_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); l3g4200d_self_check(); diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c index c200427..8a5eec4 100644 --- a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c @@ -68,6 +68,7 @@ void mma8451_self_check(void) //------------------------------------------------------------------------------------------------------------------- uint8 mma845x_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); mma8451_self_check(); diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c index 0317aa0..686550d 100644 --- a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c @@ -71,6 +71,7 @@ void mpu6050_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void mpu6050_init(void) { + simiic_init(); systick_delay_ms(STM0, 100); //ϵʱ mpu6050_self1_check(); diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c index 014b435..05f181f 100644 --- a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c @@ -38,7 +38,6 @@ #include "zf_gpio.h" #include "zf_eru.h" #include "zf_eru_dma.h" -#include "stdio.h" #include "SEEKFREE_MT9V03X.h" @@ -49,6 +48,8 @@ uint8 receive[3]; uint8 receive_num = 0; vuint8 uart_receive_flag; +uint8 link_list_num; + //Ҫõͷ int16 MT9V03X_CFG[CONFIG_FINISH][2]= { @@ -305,7 +306,7 @@ void mt9v03x_init(void) gpio_init((PIN_enum)(MT9V03X_DATA_PIN+i), GPI, 0, PULLUP); } - eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W); + link_list_num = eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W*MT9V03X_H); eru_init(MT9V03X_VSYNC_PIN, FALLING); //ʼжϣΪ½شж restoreInterrupts(interrupt_state); @@ -313,7 +314,6 @@ void mt9v03x_init(void) uint8 mt9v03x_finish_flag = 0; //һͼɼɱ־λ -uint8 now_col; //ǰڲɼ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03Xͷж // @param NULL @@ -324,16 +324,15 @@ uint8 now_col; // void mt9v03x_vsync(void) { CLEAR_GPIO_FLAG(MT9V03X_VSYNC_PIN); - now_col = 0; + if(!mt9v03x_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ { - DMA_SET_DESTINATION(MT9V03X_DMA_CH, (void *)&mt9v03x_image[0]); dma_start(MT9V03X_DMA_CH); } } - +uint8 mt9v03x_dma_int_num; //ǰDMAжϴ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03XͷDMAж // @param NULL @@ -344,16 +343,15 @@ void mt9v03x_vsync(void) void mt9v03x_dma(void) { CLEAR_DMA_FLAG(MT9V03X_DMA_CH); + mt9v03x_dma_int_num++; - now_col++; - - if(MT9V03X_H > now_col) - { - dma_start(MT9V03X_DMA_CH); - } - else + if(mt9v03x_dma_int_num >= link_list_num) { + //ɼ + mt9v03x_dma_int_num = 0; mt9v03x_finish_flag = 1;//һͼӲɼʼɼʱ3.8MS(50FPS188*120ֱ) + dma_stop(MT9V03X_DMA_CH); + } } diff --git a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h index a29edd2..0c8a785 100644 --- a/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h +++ b/Example/7-GPIO_Interrupt_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h @@ -63,9 +63,7 @@ //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ #define MT9V03X_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ - //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 - - + //ͷö typedef enum { diff --git a/Example/7-GPIO_Interrupt_Demo/USER/isr.c b/Example/7-GPIO_Interrupt_Demo/USER/isr.c index f7e3966..c6376b0 100644 --- a/Example/7-GPIO_Interrupt_Demo/USER/isr.c +++ b/Example/7-GPIO_Interrupt_Demo/USER/isr.c @@ -55,13 +55,11 @@ IFX_INTERRUPT(eru_ch0_ch4_isr, ERU_CH0_CH4_INT_SERVICE, ERU_CH0_CH4_INT_PRIO) if(GET_GPIO_FLAG(ERU_CH0_REQ4_P10_7))//ͨ0ж { CLEAR_GPIO_FLAG(ERU_CH0_REQ4_P10_7); - printf("eru ch0 be triggered\n"); } if(GET_GPIO_FLAG(ERU_CH4_REQ13_P15_5))//ͨ4ж { CLEAR_GPIO_FLAG(ERU_CH4_REQ13_P15_5); - printf("eru ch4 be triggered\n"); } } @@ -70,13 +68,11 @@ IFX_INTERRUPT(eru_ch1_ch5_isr, ERU_CH1_CH5_INT_SERVICE, ERU_CH1_CH5_INT_PRIO) if(GET_GPIO_FLAG(ERU_CH1_REQ5_P10_8))//ͨ1ж { CLEAR_GPIO_FLAG(ERU_CH1_REQ5_P10_8); - printf("eru ch1 be triggered\n"); } if(GET_GPIO_FLAG(ERU_CH5_REQ1_P15_8))//ͨ5ж { CLEAR_GPIO_FLAG(ERU_CH5_REQ1_P15_8); - printf("eru ch5 be triggered\n"); } } @@ -102,7 +98,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) if(GET_GPIO_FLAG(ERU_CH3_REQ6_P02_0))//ͨ3ж { CLEAR_GPIO_FLAG(ERU_CH3_REQ6_P02_0); - if(1 == camera_type)mt9v03x_vsync(); + if (1 == camera_type) mt9v03x_vsync(); + else if (3 == camera_type) ov7725_vsync(); } if(GET_GPIO_FLAG(ERU_CH7_REQ16_P15_1))//ͨ7ж @@ -117,7 +114,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) IFX_INTERRUPT(dma_ch5_isr, ERU_DMA_INT_SERVICE, ERU_DMA_INT_PRIO) { - if(1 == camera_type) mt9v03x_dma(); + if (1 == camera_type) mt9v03x_dma(); + else if (3 == camera_type) ov7725_dma(); } diff --git a/Example/8-EEPROM_Demo/Libraries/doc/version.txt b/Example/8-EEPROM_Demo/Libraries/doc/version.txt index b85cd50..a42bc58 100644 --- a/Example/8-EEPROM_Demo/Libraries/doc/version.txt +++ b/Example/8-EEPROM_Demo/Libraries/doc/version.txt @@ -1,9 +1,17 @@ V1.0.0 - ʼ汾 + ʼ汾 V1.0.1 ͷijжϽ޸ģжϱ־λΪ0Ųɼһͼ񣬱ַʳͻ ޸SPIʼеĴ˹̶SPI2ַ ޸STM޷ʹSTM1 - ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ \ No newline at end of file + ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ + +V1.0.2 + ޸ģIICĬʱʱΪ20 + ҪرעP20_2DzģֻĹ ע + ͷɼDMAΪlink䣬Դ󽵵DMAжϴ + ޸ĬϵIICŶ + 6050 ҪõIICģ飬ڳʼĬϵģIICʼ + С \ No newline at end of file diff --git a/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/common/common.c b/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/common/common.c index 0460d15..ac42b19 100644 --- a/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/common/common.c +++ b/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/common/common.c @@ -22,7 +22,7 @@ #include "SysSe/Bsp/Bsp.h" #include "common.h" -uint8 camera_type; +uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С diff --git a/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/common/common.h b/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/common/common.h index fe7ec63..13d03cd 100644 --- a/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/common/common.h +++ b/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/common/common.h @@ -111,7 +111,7 @@ typedef enum //ö #include -extern uint8 camera_type; +extern uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С void get_clk(void); diff --git a/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/headfile.h b/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/headfile.h index 0e8024f..e11bd83 100644 --- a/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/headfile.h +++ b/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/headfile.h @@ -62,6 +62,7 @@ #include "SEEKFREE_L3G4200D.h" #include "SEEKFREE_WIRELESS.h" #include "SEEKFREE_IPS200_PARALLEL8.h" +#include "SEEKFREE_7725.h" #endif diff --git a/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/zf_eru_dma.c b/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/zf_eru_dma.c index f7aab10..86c0158 100644 --- a/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/zf_eru_dma.c +++ b/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/zf_eru_dma.c @@ -21,9 +21,18 @@ #include "IfxDma_Dma.h" #include "IfxScuEru.h" #include "isr_config.h" +#include "zf_assert.h" #include "zf_eru_dma.h" +typedef struct +{ + Ifx_DMA_CH IFX_ALIGN(256) linked_list[8];//DMA + IfxDma_Dma_Channel channel; //DMAͨ +}DMA_LINK; + + +DMA_LINK dma_link_list; //------------------------------------------------------------------------------------------------------------------- // @brief erudmaʼ @@ -36,7 +45,7 @@ // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) { IfxDma_Dma_Channel dmaChn; //eruDMAͨ eruļeruȼΪͨ @@ -51,27 +60,85 @@ void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destinatio IfxDma_Dma_ChannelConfig cfg; IfxDma_Dma_initChannelConfig(&cfg, &dma); - cfg.transferCount = dma_count; + uint8 list_num, i; + uint16 single_channel_dma_count; + + ZF_ASSERT(!(dma_count%8));//Ϊ8ı + + + list_num = 1; + single_channel_dma_count = dma_count / list_num; + if(16384 < single_channel_dma_count) + { + while(TRUE) + { + single_channel_dma_count = dma_count / list_num; + if((single_channel_dma_count <= 16384) && !(dma_count % list_num)) + { + break; + } + list_num++; + if(list_num > 8) ZF_ASSERT(FALSE); + } + } + + + if(1 == list_num) + { + cfg.shadowControl = IfxDma_ChannelShadow_none; + cfg.operationMode = IfxDma_ChannelOperationMode_single; + cfg.shadowAddress = 0; + } + else + { + cfg.shadowControl = IfxDma_ChannelShadow_linkedList; + cfg.operationMode = IfxDma_ChannelOperationMode_continuous; + cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[1]); + } + cfg.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest; cfg.moveSize = IfxDma_ChannelMoveSize_8bit; + cfg.busPriority = IfxDma_ChannelBusPriority_high; - cfg.busPriority = IfxDma_ChannelBusPriority_high; - - cfg.sourceAddress = (unsigned)(source_addr); + cfg.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), source_addr); cfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_none; cfg.sourceCircularBufferEnabled = TRUE; - cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); cfg.destinationAddressIncrementStep = IfxDma_ChannelIncrementStep_1; - cfg.operationMode = IfxDma_ChannelOperationMode_single; - cfg.channelId = (IfxDma_ChannelId)dma_ch; - cfg.hardwareRequestEnabled = TRUE; - cfg.channelInterruptEnabled = TRUE; + cfg.channelId = (IfxDma_ChannelId)dma_ch; + cfg.hardwareRequestEnabled = FALSE; + cfg.channelInterruptEnabled = TRUE; cfg.channelInterruptPriority = ERU_DMA_INT_PRIO; cfg.channelInterruptTypeOfService = (IfxSrc_Tos)ERU_DMA_INT_SERVICE; + + + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); + + cfg.transferCount = single_channel_dma_count; + IfxDma_Dma_initChannel(&dmaChn, &cfg); + + if(1 < list_num) + { + i = 0; + while(i < list_num) + { + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr + single_channel_dma_count * i); + if(i == (list_num - 1)) cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[0]); + else cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[i+1]); + cfg.transferCount = single_channel_dma_count; + + IfxDma_Dma_initLinkedListEntry((void *)&dma_link_list.linked_list[i], &cfg); + i++; + } + } + + + IfxDma_Dma_getSrcPointer(&dma_link_list.channel)->B.CLRR = 1; + + return list_num; } diff --git a/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/zf_eru_dma.h b/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/zf_eru_dma.h index 50667ad..faef169 100644 --- a/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/zf_eru_dma.h +++ b/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/zf_eru_dma.h @@ -29,9 +29,9 @@ #define CLEAR_DMA_FLAG(dma_ch) IfxDma_clearChannelInterrupt(&MODULE_DMA, dma_ch); -#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)destination_addr) +#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr)) -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); void dma_stop(IfxDma_ChannelId dma_ch); void dma_start(IfxDma_ChannelId dma_ch); diff --git a/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/zf_gpio.c b/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/zf_gpio.c index 3c937cf..1d2466c 100644 --- a/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/zf_gpio.c +++ b/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/zf_gpio.c @@ -60,6 +60,7 @@ Ifx_P* get_port(PIN_enum pin) // @param pinmode ãòzf_gpio.hļGPIOMODE_enumöֵȷ // @return void // Sample usage: gpio_init(P00_0, GPO, 1, PUSHPULL);//P00_0ʼΪGPIOܡģʽߵƽ +// @note ҪرעP20_2DzģֻĹ //------------------------------------------------------------------------------------------------------------------- void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinmode) { diff --git a/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/zf_gpio.h b/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/zf_gpio.h index cfbd666..e3d144f 100644 --- a/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/zf_gpio.h +++ b/Example/8-EEPROM_Demo/Libraries/seekfree_libraries/zf_gpio.h @@ -38,6 +38,15 @@ typedef enum // ö #define GET_PORT_IN_ADDR(pin) (uint8 *)(&IfxPort_getAddress((IfxPort_Index)(pin/32))->IN + pin%32/8) + + +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ + + + + //------------------------------------------------------ //ͨGPIO void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinconf); diff --git a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c new file mode 100644 index 0000000..806b8d9 --- /dev/null +++ b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c @@ -0,0 +1,262 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + +#include "IfxDma.h" +#include "IfxScuEru.h" +#include "zf_stm_systick.h" +#include "zf_gpio.h" +#include "zf_eru.h" +#include "zf_eru_dma.h" +#include "SEEKFREE_IIC.h" +#include "SEEKFREE_7725.h" + + + +IFX_ALIGN(4) uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +uint8 image_dec[OV7725_H][OV7725_W]; + +uint8 ov7725_idcode = 0; + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷڲĴʼ(ڲʹãû) +// @param NULL +// @return uint8 01ɹ +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_reg_init(void) +{ + simiic_delay_set(500); + simiic_write_reg ( OV7725_DEV_ADD, OV7725_COM7, 0x80 ); //λͷ + systick_delay_ms(STM0, 50); + ov7725_idcode = simiic_read_reg( OV7725_DEV_ADD, OV7725_VER ,SCCB); + if( ov7725_idcode != OV7725_ID ) return 0; //УͷID + + //IDȷ ȻüĴ + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM4 , 0xC1); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CLKRC , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM2 , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM3 , 0xD0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM7 , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM8 , 0xCE); //0xCE:رԶع 0xCFԶع + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSTART , 0x3F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSIZE , 0x50); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSTRT , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSIZE , 0x78); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HREF , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SCAL0 , 0x0A); + simiic_write_reg(OV7725_DEV_ADD, OV7725_AWB_Ctrl0 , 0xE0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSPAuto , 0xff); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl2 , 0x0C); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl3 , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl4 , 0x00); + + if(OV7725_W == 80) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x14); + else if(OV7725_W == 160) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x28); + else if(OV7725_W == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x3c); + else if(OV7725_W == 320) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x50); + + if(OV7725_H == 60) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x1E); + else if(OV7725_H == 120) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x3c); + else if(OV7725_H == 180) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x5a); + else if(OV7725_H == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x78); + + simiic_write_reg(OV7725_DEV_ADD, OV7725_REG28 , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCH , 0x10); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCL , 0x1F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM1 , 0x0c); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM2 , 0x16); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM3 , 0x2a); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM4 , 0x4e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM5 , 0x61); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM6 , 0x6f); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM7 , 0x7b); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM8 , 0x86); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM9 , 0x8e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM10 , 0x97); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM11 , 0xa4); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM12 , 0xaf); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM13 , 0xc5); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM14 , 0xd7); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM15 , 0xe8); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SLOP , 0x20); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_RADI , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEF , 0x13); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_XC , 0x08); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFB , 0x14); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFR , 0x17); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_CTR , 0x05); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDBase , 0x99); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDMStep , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SDE , 0x04); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BRIGHT , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CNST , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SIGN , 0x06); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ0 , 0x11); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ1 , 0x02); + + + simiic_delay_set(SIMIIC_DELAY_TIME);//޸ΪĬϵ20 + return 1; + + +} + + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷɼʼ(ڲʹãû) +// @param NULL +// @return void +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +void ov7725_port_init(void) +{ + uint8 i; + camera_type = 3;//ͷ + + //ͷɼʼ + //ʼ + for(i=0; i<8; i++) + { + gpio_init((PIN_enum)(OV7725_DATA_PIN+i), GPI, 0, PULLUP); + } + eru_dma_init(OV7725_DMA_CH, GET_PORT_IN_ADDR(OV7725_DATA_PIN), image_bin[0], OV7725_PCLK_PIN, FALLING, OV7725_DMA_NUM); + eru_init(OV7725_VSYNC_PIN, FALLING); //ʼжϣΪ½شж + +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷʼ(֮úжϺɲɼͼ) +// @param NULL +// @return 0 +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_init(void) +{ + simiic_init(); + ov7725_reg_init(); //ͷĴ + ov7725_port_init(); //ͷжżDMA + return 0; +} + + + + +uint8 ov7725_finish_flag = 0; +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбeruGPIOжϣжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_vsync(void) +{ + CLEAR_GPIO_FLAG(OV7725_VSYNC_PIN); + + if(!ov7725_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ + { + DMA_SET_DESTINATION(OV7725_DMA_CH, image_bin[0]); + dma_start(OV7725_DMA_CH); + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷDMAж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбdmaжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_dma(void) +{ + CLEAR_DMA_FLAG(OV7725_DMA_CH); + ov7725_finish_flag = 1; + dma_stop(OV7725_DMA_CH); +} + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷݽѹ +// @param *data1 Դַ +// @param *data2 Ŀĵַ +// @return void +// @since v1.0 +// Sample usage: Image_Decompression(da1,dat2[0]);//һάdat1ݽѹάdat2. +//------------------------------------------------------------------------------------------------------------------- +void image_decompression(uint8 *data1,uint8 *data2) +{ + uint8 temp[2] = {0,255}; + uint16 lenth = OV7725_SIZE; + uint8 i = 8; + + + while(lenth--) + { + i = 8; + while(i--) + { + *data2++ = temp[(*data1 >> i) & 0x01]; + } + data1++; + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷδѹͼλ鿴ͼ +// @param *imgaddr ѹͼݵַ +// @param *imgsize ͼС(ֱдOV7725_SIZE) +// @return void +// @since v1.0 +// Sample usage: øúǰȳʼuart2 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_sendimg_7725(UARTN_enum uartn) +{ + uart_putchar(uartn, 0x00);uart_putchar(uartn, 0xff);uart_putchar(uartn, 0x01);uart_putchar(uartn, 0x01);//ĸֽ + uart_putbuff(uartn, image_bin[0], OV7725_SIZE); //ٷͼ +} + + + + diff --git a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h new file mode 100644 index 0000000..e513250 --- /dev/null +++ b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h @@ -0,0 +1,243 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + + +#ifndef _SEEKFREE_7725_h +#define _SEEKFREE_7725_h + +#include "common.h" +#include "IfxDma_cfg.h" +#include "zf_uart.h" + + +//ͷID +#define OV7725_ID 0x21 + +//ͷĴ +#define OV7725_GAIN 0x00 +#define OV7725_BLUE 0x01 +#define OV7725_RED 0x02 +#define OV7725_GREEN 0x03 +#define OV7725_BAVG 0x05 +#define OV7725_GAVG 0x06 +#define OV7725_RAVG 0x07 +#define OV7725_AECH 0x08 +#define OV7725_COM2 0x09 +#define OV7725_PID 0x0A +#define OV7725_VER 0x0B +#define OV7725_COM3 0x0C +#define OV7725_COM4 0x0D +#define OV7725_COM5 0x0E +#define OV7725_COM6 0x0F +#define OV7725_AEC 0x10 +#define OV7725_CLKRC 0x11 +#define OV7725_COM7 0x12 +#define OV7725_COM8 0x13 +#define OV7725_COM9 0x14 +#define OV7725_COM10 0x15 +#define OV7725_REG16 0x16 +#define OV7725_HSTART 0x17 +#define OV7725_HSIZE 0x18 +#define OV7725_VSTRT 0x19 +#define OV7725_VSIZE 0x1A +#define OV7725_PSHFT 0x1B +#define OV7725_MIDH 0x1C +#define OV7725_MIDL 0x1D +#define OV7725_LAEC 0x1F +#define OV7725_COM11 0x20 +#define OV7725_BDBase 0x22 +#define OV7725_BDMStep 0x23 +#define OV7725_AEW 0x24 +#define OV7725_AEB 0x25 +#define OV7725_VPT 0x26 +#define OV7725_REG28 0x28 +#define OV7725_HOutSize 0x29 +#define OV7725_EXHCH 0x2A +#define OV7725_EXHCL 0x2B +#define OV7725_VOutSize 0x2C +#define OV7725_ADVFL 0x2D +#define OV7725_ADVFH 0x2E +#define OV7725_YAVE 0x2F +#define OV7725_LumHTh 0x30 +#define OV7725_LumLTh 0x31 +#define OV7725_HREF 0x32 +#define OV7725_DM_LNL 0x33 +#define OV7725_DM_LNH 0x34 +#define OV7725_ADoff_B 0x35 +#define OV7725_ADoff_R 0x36 +#define OV7725_ADoff_Gb 0x37 +#define OV7725_ADoff_Gr 0x38 +#define OV7725_Off_B 0x39 +#define OV7725_Off_R 0x3A +#define OV7725_Off_Gb 0x3B +#define OV7725_Off_Gr 0x3C +#define OV7725_COM12 0x3D +#define OV7725_COM13 0x3E +#define OV7725_COM14 0x3F +#define OV7725_COM16 0x41 +#define OV7725_TGT_B 0x42 +#define OV7725_TGT_R 0x43 +#define OV7725_TGT_Gb 0x44 +#define OV7725_TGT_Gr 0x45 +#define OV7725_LC_CTR 0x46 +#define OV7725_LC_XC 0x47 +#define OV7725_LC_YC 0x48 +#define OV7725_LC_COEF 0x49 +#define OV7725_LC_RADI 0x4A +#define OV7725_LC_COEFB 0x4B +#define OV7725_LC_COEFR 0x4C +#define OV7725_FixGain 0x4D +#define OV7725_AREF1 0x4F +#define OV7725_AREF6 0x54 +#define OV7725_UFix 0x60 +#define OV7725_VFix 0x61 +#define OV7725_AWBb_blk 0x62 +#define OV7725_AWB_Ctrl0 0x63 +#define OV7725_DSP_Ctrl1 0x64 +#define OV7725_DSP_Ctrl2 0x65 +#define OV7725_DSP_Ctrl3 0x66 +#define OV7725_DSP_Ctrl4 0x67 +#define OV7725_AWB_bias 0x68 +#define OV7725_AWBCtrl1 0x69 +#define OV7725_AWBCtrl2 0x6A +#define OV7725_AWBCtrl3 0x6B +#define OV7725_AWBCtrl4 0x6C +#define OV7725_AWBCtrl5 0x6D +#define OV7725_AWBCtrl6 0x6E +#define OV7725_AWBCtrl7 0x6F +#define OV7725_AWBCtrl8 0x70 +#define OV7725_AWBCtrl9 0x71 +#define OV7725_AWBCtrl10 0x72 +#define OV7725_AWBCtrl11 0x73 +#define OV7725_AWBCtrl12 0x74 +#define OV7725_AWBCtrl13 0x75 +#define OV7725_AWBCtrl14 0x76 +#define OV7725_AWBCtrl15 0x77 +#define OV7725_AWBCtrl16 0x78 +#define OV7725_AWBCtrl17 0x79 +#define OV7725_AWBCtrl18 0x7A +#define OV7725_AWBCtrl19 0x7B +#define OV7725_AWBCtrl20 0x7C +#define OV7725_AWBCtrl21 0x7D +#define OV7725_GAM1 0x7E +#define OV7725_GAM2 0x7F +#define OV7725_GAM3 0x80 +#define OV7725_GAM4 0x81 +#define OV7725_GAM5 0x82 +#define OV7725_GAM6 0x83 +#define OV7725_GAM7 0x84 +#define OV7725_GAM8 0x85 +#define OV7725_GAM9 0x86 +#define OV7725_GAM10 0x87 +#define OV7725_GAM11 0x88 +#define OV7725_GAM12 0x89 +#define OV7725_GAM13 0x8A +#define OV7725_GAM14 0x8B +#define OV7725_GAM15 0x8C +#define OV7725_SLOP 0x8D +#define OV7725_DNSTh 0x8E +#define OV7725_EDGE0 0x8F +#define OV7725_EDGE1 0x90 +#define OV7725_DNSOff 0x91 +#define OV7725_EDGE2 0x92 +#define OV7725_EDGE3 0x93 +#define OV7725_MTX1 0x94 +#define OV7725_MTX2 0x95 +#define OV7725_MTX3 0x96 +#define OV7725_MTX4 0x97 +#define OV7725_MTX5 0x98 +#define OV7725_MTX6 0x99 +#define OV7725_MTX_Ctrl 0x9A +#define OV7725_BRIGHT 0x9B +#define OV7725_CNST 0x9C +#define OV7725_UVADJ0 0x9E +#define OV7725_UVADJ1 0x9F +#define OV7725_SCAL0 0xA0 +#define OV7725_SCAL1 0xA1 +#define OV7725_SCAL2 0xA2 +#define OV7725_SDE 0xA6 +#define OV7725_USAT 0xA7 +#define OV7725_VSAT 0xA8 +#define OV7725_HUECOS 0xA9 +#define OV7725_HUESIN 0xAA +#define OV7725_SIGN 0xAB +#define OV7725_DSPAuto 0xAC + + +#define OV7725_DEV_ADD 0x42>>1 + + +//ͷ +#define OV7725_W 160 //ͷͼ ò 80 160 240 320 +#define OV7725_H 120 //ͷͼ߶ ò 60 120 180 240 +#define OV7725_SIZE (OV7725_W * OV7725_H/8 ) //ͼռÿռС +#define OV7725_DMA_NUM (OV7725_SIZE) //һͼDMAɼ + + +//-------------------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------------------- +#define OV7725_VSYNC_PIN ERU_CH3_REQ6_P02_0 //ж ѡΧοERU_PIN_enumö ѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DATA_PIN P00_0 //D0 D0ΪP00_0 ôD1ʹõΪP00_1 + //òP00_0P02_0P15_0Ϊ + +#define OV7725_PCLK_PIN ERU_CH2_REQ14_P02_1 //ʱ ѡΧοERU_PIN_enumö 볡жѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ + //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 + + + +extern uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +extern uint8 image_dec[OV7725_H][OV7725_W]; //ͼѹ + +extern uint8 ov7725_finish_flag; //ͼɼɱ־λ + + +// +uint8 ov7725_init(void); +void ov7725_vsync(void); +void ov7725_dma(void); +void image_decompression(uint8 *data1,uint8 *data2); +void seekfree_sendimg_7725(UARTN_enum uartn); + + + +#endif + + + diff --git a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c index 095f9e3..5d167c9 100644 --- a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c +++ b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c @@ -68,6 +68,7 @@ void icm20602_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void icm20602_init(void) { + simiic_init(); systick_delay_ms(STM0, 10); //ϵʱ // diff --git a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c index 196fd57..f56a41a 100644 --- a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c +++ b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c @@ -50,7 +50,7 @@ uint8 IIC_num; // -static uint16 simiic_delay_time=100; //ICMȴӦΪ100 +static uint16 simiic_delay_time = SIMIIC_DELAY_TIME; //ICMȴӦΪ20 //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h index 293a02a..6a9c1e3 100644 --- a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h +++ b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h @@ -34,8 +34,12 @@ -#define SEEKFREE_SCL P13_0 //SCL ΪIO -#define SEEKFREE_SDA P13_1 //SDA ΪIO +#define SEEKFREE_SCL P02_3 //SCL ΪIO +#define SEEKFREE_SDA P02_2 //SDA ΪIO + + +#define SIMIIC_DELAY_TIME 20 + typedef enum IIC //DACģ { diff --git a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c index 0f0c23a..5deb7d3 100644 --- a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c +++ b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c @@ -65,6 +65,7 @@ void l3g4200d_self_check(void) //------------------------------------------------------------------------------------------------------------------- void l3g4200d_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); l3g4200d_self_check(); diff --git a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c index c200427..8a5eec4 100644 --- a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c +++ b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c @@ -68,6 +68,7 @@ void mma8451_self_check(void) //------------------------------------------------------------------------------------------------------------------- uint8 mma845x_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); mma8451_self_check(); diff --git a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c index 0317aa0..686550d 100644 --- a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c +++ b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c @@ -71,6 +71,7 @@ void mpu6050_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void mpu6050_init(void) { + simiic_init(); systick_delay_ms(STM0, 100); //ϵʱ mpu6050_self1_check(); diff --git a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c index 014b435..05f181f 100644 --- a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c +++ b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c @@ -38,7 +38,6 @@ #include "zf_gpio.h" #include "zf_eru.h" #include "zf_eru_dma.h" -#include "stdio.h" #include "SEEKFREE_MT9V03X.h" @@ -49,6 +48,8 @@ uint8 receive[3]; uint8 receive_num = 0; vuint8 uart_receive_flag; +uint8 link_list_num; + //Ҫõͷ int16 MT9V03X_CFG[CONFIG_FINISH][2]= { @@ -305,7 +306,7 @@ void mt9v03x_init(void) gpio_init((PIN_enum)(MT9V03X_DATA_PIN+i), GPI, 0, PULLUP); } - eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W); + link_list_num = eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W*MT9V03X_H); eru_init(MT9V03X_VSYNC_PIN, FALLING); //ʼжϣΪ½شж restoreInterrupts(interrupt_state); @@ -313,7 +314,6 @@ void mt9v03x_init(void) uint8 mt9v03x_finish_flag = 0; //һͼɼɱ־λ -uint8 now_col; //ǰڲɼ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03Xͷж // @param NULL @@ -324,16 +324,15 @@ uint8 now_col; // void mt9v03x_vsync(void) { CLEAR_GPIO_FLAG(MT9V03X_VSYNC_PIN); - now_col = 0; + if(!mt9v03x_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ { - DMA_SET_DESTINATION(MT9V03X_DMA_CH, (void *)&mt9v03x_image[0]); dma_start(MT9V03X_DMA_CH); } } - +uint8 mt9v03x_dma_int_num; //ǰDMAжϴ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03XͷDMAж // @param NULL @@ -344,16 +343,15 @@ void mt9v03x_vsync(void) void mt9v03x_dma(void) { CLEAR_DMA_FLAG(MT9V03X_DMA_CH); + mt9v03x_dma_int_num++; - now_col++; - - if(MT9V03X_H > now_col) - { - dma_start(MT9V03X_DMA_CH); - } - else + if(mt9v03x_dma_int_num >= link_list_num) { + //ɼ + mt9v03x_dma_int_num = 0; mt9v03x_finish_flag = 1;//һͼӲɼʼɼʱ3.8MS(50FPS188*120ֱ) + dma_stop(MT9V03X_DMA_CH); + } } diff --git a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h index a29edd2..0c8a785 100644 --- a/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h +++ b/Example/8-EEPROM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h @@ -63,9 +63,7 @@ //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ #define MT9V03X_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ - //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 - - + //ͷö typedef enum { diff --git a/Example/8-EEPROM_Demo/USER/isr.c b/Example/8-EEPROM_Demo/USER/isr.c index 15666f2..c6376b0 100644 --- a/Example/8-EEPROM_Demo/USER/isr.c +++ b/Example/8-EEPROM_Demo/USER/isr.c @@ -98,7 +98,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) if(GET_GPIO_FLAG(ERU_CH3_REQ6_P02_0))//ͨ3ж { CLEAR_GPIO_FLAG(ERU_CH3_REQ6_P02_0); - if(1 == camera_type)mt9v03x_vsync(); + if (1 == camera_type) mt9v03x_vsync(); + else if (3 == camera_type) ov7725_vsync(); } if(GET_GPIO_FLAG(ERU_CH7_REQ16_P15_1))//ͨ7ж @@ -113,7 +114,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) IFX_INTERRUPT(dma_ch5_isr, ERU_DMA_INT_SERVICE, ERU_DMA_INT_PRIO) { - if(1 == camera_type) mt9v03x_dma(); + if (1 == camera_type) mt9v03x_dma(); + else if (3 == camera_type) ov7725_dma(); } diff --git a/Example/9-PWM_Demo/Libraries/doc/version.txt b/Example/9-PWM_Demo/Libraries/doc/version.txt index b85cd50..a42bc58 100644 --- a/Example/9-PWM_Demo/Libraries/doc/version.txt +++ b/Example/9-PWM_Demo/Libraries/doc/version.txt @@ -1,9 +1,17 @@ V1.0.0 - ʼ汾 + ʼ汾 V1.0.1 ͷijжϽ޸ģжϱ־λΪ0Ųɼһͼ񣬱ַʳͻ ޸SPIʼеĴ˹̶SPI2ַ ޸STM޷ʹSTM1 - ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ \ No newline at end of file + ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ + +V1.0.2 + ޸ģIICĬʱʱΪ20 + ҪرעP20_2DzģֻĹ ע + ͷɼDMAΪlink䣬Դ󽵵DMAжϴ + ޸ĬϵIICŶ + 6050 ҪõIICģ飬ڳʼĬϵģIICʼ + С \ No newline at end of file diff --git a/Example/9-PWM_Demo/Libraries/seekfree_libraries/common/common.c b/Example/9-PWM_Demo/Libraries/seekfree_libraries/common/common.c index 0460d15..ac42b19 100644 --- a/Example/9-PWM_Demo/Libraries/seekfree_libraries/common/common.c +++ b/Example/9-PWM_Demo/Libraries/seekfree_libraries/common/common.c @@ -22,7 +22,7 @@ #include "SysSe/Bsp/Bsp.h" #include "common.h" -uint8 camera_type; +uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С diff --git a/Example/9-PWM_Demo/Libraries/seekfree_libraries/common/common.h b/Example/9-PWM_Demo/Libraries/seekfree_libraries/common/common.h index fe7ec63..13d03cd 100644 --- a/Example/9-PWM_Demo/Libraries/seekfree_libraries/common/common.h +++ b/Example/9-PWM_Demo/Libraries/seekfree_libraries/common/common.h @@ -111,7 +111,7 @@ typedef enum //ö #include -extern uint8 camera_type; +extern uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С void get_clk(void); diff --git a/Example/9-PWM_Demo/Libraries/seekfree_libraries/headfile.h b/Example/9-PWM_Demo/Libraries/seekfree_libraries/headfile.h index 0e8024f..e11bd83 100644 --- a/Example/9-PWM_Demo/Libraries/seekfree_libraries/headfile.h +++ b/Example/9-PWM_Demo/Libraries/seekfree_libraries/headfile.h @@ -62,6 +62,7 @@ #include "SEEKFREE_L3G4200D.h" #include "SEEKFREE_WIRELESS.h" #include "SEEKFREE_IPS200_PARALLEL8.h" +#include "SEEKFREE_7725.h" #endif diff --git a/Example/9-PWM_Demo/Libraries/seekfree_libraries/zf_eru_dma.c b/Example/9-PWM_Demo/Libraries/seekfree_libraries/zf_eru_dma.c index f7aab10..86c0158 100644 --- a/Example/9-PWM_Demo/Libraries/seekfree_libraries/zf_eru_dma.c +++ b/Example/9-PWM_Demo/Libraries/seekfree_libraries/zf_eru_dma.c @@ -21,9 +21,18 @@ #include "IfxDma_Dma.h" #include "IfxScuEru.h" #include "isr_config.h" +#include "zf_assert.h" #include "zf_eru_dma.h" +typedef struct +{ + Ifx_DMA_CH IFX_ALIGN(256) linked_list[8];//DMA + IfxDma_Dma_Channel channel; //DMAͨ +}DMA_LINK; + + +DMA_LINK dma_link_list; //------------------------------------------------------------------------------------------------------------------- // @brief erudmaʼ @@ -36,7 +45,7 @@ // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) { IfxDma_Dma_Channel dmaChn; //eruDMAͨ eruļeruȼΪͨ @@ -51,27 +60,85 @@ void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destinatio IfxDma_Dma_ChannelConfig cfg; IfxDma_Dma_initChannelConfig(&cfg, &dma); - cfg.transferCount = dma_count; + uint8 list_num, i; + uint16 single_channel_dma_count; + + ZF_ASSERT(!(dma_count%8));//Ϊ8ı + + + list_num = 1; + single_channel_dma_count = dma_count / list_num; + if(16384 < single_channel_dma_count) + { + while(TRUE) + { + single_channel_dma_count = dma_count / list_num; + if((single_channel_dma_count <= 16384) && !(dma_count % list_num)) + { + break; + } + list_num++; + if(list_num > 8) ZF_ASSERT(FALSE); + } + } + + + if(1 == list_num) + { + cfg.shadowControl = IfxDma_ChannelShadow_none; + cfg.operationMode = IfxDma_ChannelOperationMode_single; + cfg.shadowAddress = 0; + } + else + { + cfg.shadowControl = IfxDma_ChannelShadow_linkedList; + cfg.operationMode = IfxDma_ChannelOperationMode_continuous; + cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[1]); + } + cfg.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest; cfg.moveSize = IfxDma_ChannelMoveSize_8bit; + cfg.busPriority = IfxDma_ChannelBusPriority_high; - cfg.busPriority = IfxDma_ChannelBusPriority_high; - - cfg.sourceAddress = (unsigned)(source_addr); + cfg.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), source_addr); cfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_none; cfg.sourceCircularBufferEnabled = TRUE; - cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); cfg.destinationAddressIncrementStep = IfxDma_ChannelIncrementStep_1; - cfg.operationMode = IfxDma_ChannelOperationMode_single; - cfg.channelId = (IfxDma_ChannelId)dma_ch; - cfg.hardwareRequestEnabled = TRUE; - cfg.channelInterruptEnabled = TRUE; + cfg.channelId = (IfxDma_ChannelId)dma_ch; + cfg.hardwareRequestEnabled = FALSE; + cfg.channelInterruptEnabled = TRUE; cfg.channelInterruptPriority = ERU_DMA_INT_PRIO; cfg.channelInterruptTypeOfService = (IfxSrc_Tos)ERU_DMA_INT_SERVICE; + + + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); + + cfg.transferCount = single_channel_dma_count; + IfxDma_Dma_initChannel(&dmaChn, &cfg); + + if(1 < list_num) + { + i = 0; + while(i < list_num) + { + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr + single_channel_dma_count * i); + if(i == (list_num - 1)) cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[0]); + else cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[i+1]); + cfg.transferCount = single_channel_dma_count; + + IfxDma_Dma_initLinkedListEntry((void *)&dma_link_list.linked_list[i], &cfg); + i++; + } + } + + + IfxDma_Dma_getSrcPointer(&dma_link_list.channel)->B.CLRR = 1; + + return list_num; } diff --git a/Example/9-PWM_Demo/Libraries/seekfree_libraries/zf_eru_dma.h b/Example/9-PWM_Demo/Libraries/seekfree_libraries/zf_eru_dma.h index 50667ad..faef169 100644 --- a/Example/9-PWM_Demo/Libraries/seekfree_libraries/zf_eru_dma.h +++ b/Example/9-PWM_Demo/Libraries/seekfree_libraries/zf_eru_dma.h @@ -29,9 +29,9 @@ #define CLEAR_DMA_FLAG(dma_ch) IfxDma_clearChannelInterrupt(&MODULE_DMA, dma_ch); -#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)destination_addr) +#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr)) -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); void dma_stop(IfxDma_ChannelId dma_ch); void dma_start(IfxDma_ChannelId dma_ch); diff --git a/Example/9-PWM_Demo/Libraries/seekfree_libraries/zf_gpio.c b/Example/9-PWM_Demo/Libraries/seekfree_libraries/zf_gpio.c index 3c937cf..1d2466c 100644 --- a/Example/9-PWM_Demo/Libraries/seekfree_libraries/zf_gpio.c +++ b/Example/9-PWM_Demo/Libraries/seekfree_libraries/zf_gpio.c @@ -60,6 +60,7 @@ Ifx_P* get_port(PIN_enum pin) // @param pinmode ãòzf_gpio.hļGPIOMODE_enumöֵȷ // @return void // Sample usage: gpio_init(P00_0, GPO, 1, PUSHPULL);//P00_0ʼΪGPIOܡģʽߵƽ +// @note ҪرעP20_2DzģֻĹ //------------------------------------------------------------------------------------------------------------------- void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinmode) { diff --git a/Example/9-PWM_Demo/Libraries/seekfree_libraries/zf_gpio.h b/Example/9-PWM_Demo/Libraries/seekfree_libraries/zf_gpio.h index cfbd666..e3d144f 100644 --- a/Example/9-PWM_Demo/Libraries/seekfree_libraries/zf_gpio.h +++ b/Example/9-PWM_Demo/Libraries/seekfree_libraries/zf_gpio.h @@ -38,6 +38,15 @@ typedef enum // ö #define GET_PORT_IN_ADDR(pin) (uint8 *)(&IfxPort_getAddress((IfxPort_Index)(pin/32))->IN + pin%32/8) + + +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ + + + + //------------------------------------------------------ //ͨGPIO void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinconf); diff --git a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c new file mode 100644 index 0000000..806b8d9 --- /dev/null +++ b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.c @@ -0,0 +1,262 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + +#include "IfxDma.h" +#include "IfxScuEru.h" +#include "zf_stm_systick.h" +#include "zf_gpio.h" +#include "zf_eru.h" +#include "zf_eru_dma.h" +#include "SEEKFREE_IIC.h" +#include "SEEKFREE_7725.h" + + + +IFX_ALIGN(4) uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +uint8 image_dec[OV7725_H][OV7725_W]; + +uint8 ov7725_idcode = 0; + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷڲĴʼ(ڲʹãû) +// @param NULL +// @return uint8 01ɹ +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_reg_init(void) +{ + simiic_delay_set(500); + simiic_write_reg ( OV7725_DEV_ADD, OV7725_COM7, 0x80 ); //λͷ + systick_delay_ms(STM0, 50); + ov7725_idcode = simiic_read_reg( OV7725_DEV_ADD, OV7725_VER ,SCCB); + if( ov7725_idcode != OV7725_ID ) return 0; //УͷID + + //IDȷ ȻüĴ + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM4 , 0xC1); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CLKRC , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM2 , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM3 , 0xD0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM7 , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM8 , 0xCE); //0xCE:رԶع 0xCFԶع + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSTART , 0x3F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSIZE , 0x50); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSTRT , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSIZE , 0x78); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HREF , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SCAL0 , 0x0A); + simiic_write_reg(OV7725_DEV_ADD, OV7725_AWB_Ctrl0 , 0xE0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSPAuto , 0xff); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl2 , 0x0C); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl3 , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl4 , 0x00); + + if(OV7725_W == 80) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x14); + else if(OV7725_W == 160) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x28); + else if(OV7725_W == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x3c); + else if(OV7725_W == 320) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x50); + + if(OV7725_H == 60) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x1E); + else if(OV7725_H == 120) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x3c); + else if(OV7725_H == 180) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x5a); + else if(OV7725_H == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x78); + + simiic_write_reg(OV7725_DEV_ADD, OV7725_REG28 , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCH , 0x10); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCL , 0x1F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM1 , 0x0c); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM2 , 0x16); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM3 , 0x2a); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM4 , 0x4e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM5 , 0x61); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM6 , 0x6f); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM7 , 0x7b); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM8 , 0x86); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM9 , 0x8e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM10 , 0x97); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM11 , 0xa4); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM12 , 0xaf); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM13 , 0xc5); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM14 , 0xd7); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM15 , 0xe8); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SLOP , 0x20); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_RADI , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEF , 0x13); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_XC , 0x08); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFB , 0x14); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFR , 0x17); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_CTR , 0x05); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDBase , 0x99); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDMStep , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SDE , 0x04); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BRIGHT , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CNST , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SIGN , 0x06); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ0 , 0x11); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ1 , 0x02); + + + simiic_delay_set(SIMIIC_DELAY_TIME);//޸ΪĬϵ20 + return 1; + + +} + + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷɼʼ(ڲʹãû) +// @param NULL +// @return void +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +void ov7725_port_init(void) +{ + uint8 i; + camera_type = 3;//ͷ + + //ͷɼʼ + //ʼ + for(i=0; i<8; i++) + { + gpio_init((PIN_enum)(OV7725_DATA_PIN+i), GPI, 0, PULLUP); + } + eru_dma_init(OV7725_DMA_CH, GET_PORT_IN_ADDR(OV7725_DATA_PIN), image_bin[0], OV7725_PCLK_PIN, FALLING, OV7725_DMA_NUM); + eru_init(OV7725_VSYNC_PIN, FALLING); //ʼжϣΪ½شж + +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷʼ(֮úжϺɲɼͼ) +// @param NULL +// @return 0 +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_init(void) +{ + simiic_init(); + ov7725_reg_init(); //ͷĴ + ov7725_port_init(); //ͷжżDMA + return 0; +} + + + + +uint8 ov7725_finish_flag = 0; +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбeruGPIOжϣжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_vsync(void) +{ + CLEAR_GPIO_FLAG(OV7725_VSYNC_PIN); + + if(!ov7725_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ + { + DMA_SET_DESTINATION(OV7725_DMA_CH, image_bin[0]); + dma_start(OV7725_DMA_CH); + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷDMAж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбdmaжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_dma(void) +{ + CLEAR_DMA_FLAG(OV7725_DMA_CH); + ov7725_finish_flag = 1; + dma_stop(OV7725_DMA_CH); +} + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷݽѹ +// @param *data1 Դַ +// @param *data2 Ŀĵַ +// @return void +// @since v1.0 +// Sample usage: Image_Decompression(da1,dat2[0]);//һάdat1ݽѹάdat2. +//------------------------------------------------------------------------------------------------------------------- +void image_decompression(uint8 *data1,uint8 *data2) +{ + uint8 temp[2] = {0,255}; + uint16 lenth = OV7725_SIZE; + uint8 i = 8; + + + while(lenth--) + { + i = 8; + while(i--) + { + *data2++ = temp[(*data1 >> i) & 0x01]; + } + data1++; + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷδѹͼλ鿴ͼ +// @param *imgaddr ѹͼݵַ +// @param *imgsize ͼС(ֱдOV7725_SIZE) +// @return void +// @since v1.0 +// Sample usage: øúǰȳʼuart2 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_sendimg_7725(UARTN_enum uartn) +{ + uart_putchar(uartn, 0x00);uart_putchar(uartn, 0xff);uart_putchar(uartn, 0x01);uart_putchar(uartn, 0x01);//ĸֽ + uart_putbuff(uartn, image_bin[0], OV7725_SIZE); //ٷͼ +} + + + + diff --git a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h new file mode 100644 index 0000000..e513250 --- /dev/null +++ b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_7725.h @@ -0,0 +1,243 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + + +#ifndef _SEEKFREE_7725_h +#define _SEEKFREE_7725_h + +#include "common.h" +#include "IfxDma_cfg.h" +#include "zf_uart.h" + + +//ͷID +#define OV7725_ID 0x21 + +//ͷĴ +#define OV7725_GAIN 0x00 +#define OV7725_BLUE 0x01 +#define OV7725_RED 0x02 +#define OV7725_GREEN 0x03 +#define OV7725_BAVG 0x05 +#define OV7725_GAVG 0x06 +#define OV7725_RAVG 0x07 +#define OV7725_AECH 0x08 +#define OV7725_COM2 0x09 +#define OV7725_PID 0x0A +#define OV7725_VER 0x0B +#define OV7725_COM3 0x0C +#define OV7725_COM4 0x0D +#define OV7725_COM5 0x0E +#define OV7725_COM6 0x0F +#define OV7725_AEC 0x10 +#define OV7725_CLKRC 0x11 +#define OV7725_COM7 0x12 +#define OV7725_COM8 0x13 +#define OV7725_COM9 0x14 +#define OV7725_COM10 0x15 +#define OV7725_REG16 0x16 +#define OV7725_HSTART 0x17 +#define OV7725_HSIZE 0x18 +#define OV7725_VSTRT 0x19 +#define OV7725_VSIZE 0x1A +#define OV7725_PSHFT 0x1B +#define OV7725_MIDH 0x1C +#define OV7725_MIDL 0x1D +#define OV7725_LAEC 0x1F +#define OV7725_COM11 0x20 +#define OV7725_BDBase 0x22 +#define OV7725_BDMStep 0x23 +#define OV7725_AEW 0x24 +#define OV7725_AEB 0x25 +#define OV7725_VPT 0x26 +#define OV7725_REG28 0x28 +#define OV7725_HOutSize 0x29 +#define OV7725_EXHCH 0x2A +#define OV7725_EXHCL 0x2B +#define OV7725_VOutSize 0x2C +#define OV7725_ADVFL 0x2D +#define OV7725_ADVFH 0x2E +#define OV7725_YAVE 0x2F +#define OV7725_LumHTh 0x30 +#define OV7725_LumLTh 0x31 +#define OV7725_HREF 0x32 +#define OV7725_DM_LNL 0x33 +#define OV7725_DM_LNH 0x34 +#define OV7725_ADoff_B 0x35 +#define OV7725_ADoff_R 0x36 +#define OV7725_ADoff_Gb 0x37 +#define OV7725_ADoff_Gr 0x38 +#define OV7725_Off_B 0x39 +#define OV7725_Off_R 0x3A +#define OV7725_Off_Gb 0x3B +#define OV7725_Off_Gr 0x3C +#define OV7725_COM12 0x3D +#define OV7725_COM13 0x3E +#define OV7725_COM14 0x3F +#define OV7725_COM16 0x41 +#define OV7725_TGT_B 0x42 +#define OV7725_TGT_R 0x43 +#define OV7725_TGT_Gb 0x44 +#define OV7725_TGT_Gr 0x45 +#define OV7725_LC_CTR 0x46 +#define OV7725_LC_XC 0x47 +#define OV7725_LC_YC 0x48 +#define OV7725_LC_COEF 0x49 +#define OV7725_LC_RADI 0x4A +#define OV7725_LC_COEFB 0x4B +#define OV7725_LC_COEFR 0x4C +#define OV7725_FixGain 0x4D +#define OV7725_AREF1 0x4F +#define OV7725_AREF6 0x54 +#define OV7725_UFix 0x60 +#define OV7725_VFix 0x61 +#define OV7725_AWBb_blk 0x62 +#define OV7725_AWB_Ctrl0 0x63 +#define OV7725_DSP_Ctrl1 0x64 +#define OV7725_DSP_Ctrl2 0x65 +#define OV7725_DSP_Ctrl3 0x66 +#define OV7725_DSP_Ctrl4 0x67 +#define OV7725_AWB_bias 0x68 +#define OV7725_AWBCtrl1 0x69 +#define OV7725_AWBCtrl2 0x6A +#define OV7725_AWBCtrl3 0x6B +#define OV7725_AWBCtrl4 0x6C +#define OV7725_AWBCtrl5 0x6D +#define OV7725_AWBCtrl6 0x6E +#define OV7725_AWBCtrl7 0x6F +#define OV7725_AWBCtrl8 0x70 +#define OV7725_AWBCtrl9 0x71 +#define OV7725_AWBCtrl10 0x72 +#define OV7725_AWBCtrl11 0x73 +#define OV7725_AWBCtrl12 0x74 +#define OV7725_AWBCtrl13 0x75 +#define OV7725_AWBCtrl14 0x76 +#define OV7725_AWBCtrl15 0x77 +#define OV7725_AWBCtrl16 0x78 +#define OV7725_AWBCtrl17 0x79 +#define OV7725_AWBCtrl18 0x7A +#define OV7725_AWBCtrl19 0x7B +#define OV7725_AWBCtrl20 0x7C +#define OV7725_AWBCtrl21 0x7D +#define OV7725_GAM1 0x7E +#define OV7725_GAM2 0x7F +#define OV7725_GAM3 0x80 +#define OV7725_GAM4 0x81 +#define OV7725_GAM5 0x82 +#define OV7725_GAM6 0x83 +#define OV7725_GAM7 0x84 +#define OV7725_GAM8 0x85 +#define OV7725_GAM9 0x86 +#define OV7725_GAM10 0x87 +#define OV7725_GAM11 0x88 +#define OV7725_GAM12 0x89 +#define OV7725_GAM13 0x8A +#define OV7725_GAM14 0x8B +#define OV7725_GAM15 0x8C +#define OV7725_SLOP 0x8D +#define OV7725_DNSTh 0x8E +#define OV7725_EDGE0 0x8F +#define OV7725_EDGE1 0x90 +#define OV7725_DNSOff 0x91 +#define OV7725_EDGE2 0x92 +#define OV7725_EDGE3 0x93 +#define OV7725_MTX1 0x94 +#define OV7725_MTX2 0x95 +#define OV7725_MTX3 0x96 +#define OV7725_MTX4 0x97 +#define OV7725_MTX5 0x98 +#define OV7725_MTX6 0x99 +#define OV7725_MTX_Ctrl 0x9A +#define OV7725_BRIGHT 0x9B +#define OV7725_CNST 0x9C +#define OV7725_UVADJ0 0x9E +#define OV7725_UVADJ1 0x9F +#define OV7725_SCAL0 0xA0 +#define OV7725_SCAL1 0xA1 +#define OV7725_SCAL2 0xA2 +#define OV7725_SDE 0xA6 +#define OV7725_USAT 0xA7 +#define OV7725_VSAT 0xA8 +#define OV7725_HUECOS 0xA9 +#define OV7725_HUESIN 0xAA +#define OV7725_SIGN 0xAB +#define OV7725_DSPAuto 0xAC + + +#define OV7725_DEV_ADD 0x42>>1 + + +//ͷ +#define OV7725_W 160 //ͷͼ ò 80 160 240 320 +#define OV7725_H 120 //ͷͼ߶ ò 60 120 180 240 +#define OV7725_SIZE (OV7725_W * OV7725_H/8 ) //ͼռÿռС +#define OV7725_DMA_NUM (OV7725_SIZE) //һͼDMAɼ + + +//-------------------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------------------- +#define OV7725_VSYNC_PIN ERU_CH3_REQ6_P02_0 //ж ѡΧοERU_PIN_enumö ѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DATA_PIN P00_0 //D0 D0ΪP00_0 ôD1ʹõΪP00_1 + //òP00_0P02_0P15_0Ϊ + +#define OV7725_PCLK_PIN ERU_CH2_REQ14_P02_1 //ʱ ѡΧοERU_PIN_enumö 볡жѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ + //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 + + + +extern uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +extern uint8 image_dec[OV7725_H][OV7725_W]; //ͼѹ + +extern uint8 ov7725_finish_flag; //ͼɼɱ־λ + + +// +uint8 ov7725_init(void); +void ov7725_vsync(void); +void ov7725_dma(void); +void image_decompression(uint8 *data1,uint8 *data2); +void seekfree_sendimg_7725(UARTN_enum uartn); + + + +#endif + + + diff --git a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c index 095f9e3..5d167c9 100644 --- a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c +++ b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c @@ -68,6 +68,7 @@ void icm20602_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void icm20602_init(void) { + simiic_init(); systick_delay_ms(STM0, 10); //ϵʱ // diff --git a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c index 196fd57..f56a41a 100644 --- a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c +++ b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.c @@ -50,7 +50,7 @@ uint8 IIC_num; // -static uint16 simiic_delay_time=100; //ICMȴӦΪ100 +static uint16 simiic_delay_time = SIMIIC_DELAY_TIME; //ICMȴӦΪ20 //------------------------------------------------------------------------------------------------------------------- diff --git a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h index 293a02a..6a9c1e3 100644 --- a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h +++ b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_IIC.h @@ -34,8 +34,12 @@ -#define SEEKFREE_SCL P13_0 //SCL ΪIO -#define SEEKFREE_SDA P13_1 //SDA ΪIO +#define SEEKFREE_SCL P02_3 //SCL ΪIO +#define SEEKFREE_SDA P02_2 //SDA ΪIO + + +#define SIMIIC_DELAY_TIME 20 + typedef enum IIC //DACģ { diff --git a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c index 0f0c23a..5deb7d3 100644 --- a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c +++ b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c @@ -65,6 +65,7 @@ void l3g4200d_self_check(void) //------------------------------------------------------------------------------------------------------------------- void l3g4200d_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); l3g4200d_self_check(); diff --git a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c index c200427..8a5eec4 100644 --- a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c +++ b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c @@ -68,6 +68,7 @@ void mma8451_self_check(void) //------------------------------------------------------------------------------------------------------------------- uint8 mma845x_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); mma8451_self_check(); diff --git a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c index 0317aa0..686550d 100644 --- a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c +++ b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c @@ -71,6 +71,7 @@ void mpu6050_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void mpu6050_init(void) { + simiic_init(); systick_delay_ms(STM0, 100); //ϵʱ mpu6050_self1_check(); diff --git a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c index 014b435..05f181f 100644 --- a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c +++ b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c @@ -38,7 +38,6 @@ #include "zf_gpio.h" #include "zf_eru.h" #include "zf_eru_dma.h" -#include "stdio.h" #include "SEEKFREE_MT9V03X.h" @@ -49,6 +48,8 @@ uint8 receive[3]; uint8 receive_num = 0; vuint8 uart_receive_flag; +uint8 link_list_num; + //Ҫõͷ int16 MT9V03X_CFG[CONFIG_FINISH][2]= { @@ -305,7 +306,7 @@ void mt9v03x_init(void) gpio_init((PIN_enum)(MT9V03X_DATA_PIN+i), GPI, 0, PULLUP); } - eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W); + link_list_num = eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W*MT9V03X_H); eru_init(MT9V03X_VSYNC_PIN, FALLING); //ʼжϣΪ½شж restoreInterrupts(interrupt_state); @@ -313,7 +314,6 @@ void mt9v03x_init(void) uint8 mt9v03x_finish_flag = 0; //һͼɼɱ־λ -uint8 now_col; //ǰڲɼ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03Xͷж // @param NULL @@ -324,16 +324,15 @@ uint8 now_col; // void mt9v03x_vsync(void) { CLEAR_GPIO_FLAG(MT9V03X_VSYNC_PIN); - now_col = 0; + if(!mt9v03x_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ { - DMA_SET_DESTINATION(MT9V03X_DMA_CH, (void *)&mt9v03x_image[0]); dma_start(MT9V03X_DMA_CH); } } - +uint8 mt9v03x_dma_int_num; //ǰDMAжϴ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03XͷDMAж // @param NULL @@ -344,16 +343,15 @@ void mt9v03x_vsync(void) void mt9v03x_dma(void) { CLEAR_DMA_FLAG(MT9V03X_DMA_CH); + mt9v03x_dma_int_num++; - now_col++; - - if(MT9V03X_H > now_col) - { - dma_start(MT9V03X_DMA_CH); - } - else + if(mt9v03x_dma_int_num >= link_list_num) { + //ɼ + mt9v03x_dma_int_num = 0; mt9v03x_finish_flag = 1;//һͼӲɼʼɼʱ3.8MS(50FPS188*120ֱ) + dma_stop(MT9V03X_DMA_CH); + } } diff --git a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h index a29edd2..0c8a785 100644 --- a/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h +++ b/Example/9-PWM_Demo/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h @@ -63,9 +63,7 @@ //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ #define MT9V03X_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ - //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 - - + //ͷö typedef enum { diff --git a/Example/9-PWM_Demo/USER/isr.c b/Example/9-PWM_Demo/USER/isr.c index 15666f2..c6376b0 100644 --- a/Example/9-PWM_Demo/USER/isr.c +++ b/Example/9-PWM_Demo/USER/isr.c @@ -98,7 +98,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) if(GET_GPIO_FLAG(ERU_CH3_REQ6_P02_0))//ͨ3ж { CLEAR_GPIO_FLAG(ERU_CH3_REQ6_P02_0); - if(1 == camera_type)mt9v03x_vsync(); + if (1 == camera_type) mt9v03x_vsync(); + else if (3 == camera_type) ov7725_vsync(); } if(GET_GPIO_FLAG(ERU_CH7_REQ16_P15_1))//ͨ7ж @@ -113,7 +114,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) IFX_INTERRUPT(dma_ch5_isr, ERU_DMA_INT_SERVICE, ERU_DMA_INT_PRIO) { - if(1 == camera_type) mt9v03x_dma(); + if (1 == camera_type) mt9v03x_dma(); + else if (3 == camera_type) ov7725_dma(); } diff --git a/Seekfree_TC264_Opensource_Library/Libraries/doc/version.txt b/Seekfree_TC264_Opensource_Library/Libraries/doc/version.txt index b85cd50..a42bc58 100644 --- a/Seekfree_TC264_Opensource_Library/Libraries/doc/version.txt +++ b/Seekfree_TC264_Opensource_Library/Libraries/doc/version.txt @@ -1,9 +1,17 @@ V1.0.0 - ʼ汾 + ʼ汾 V1.0.1 ͷijжϽ޸ģжϱ־λΪ0Ųɼһͼ񣬱ַʳͻ ޸SPIʼеĴ˹̶SPI2ַ ޸STM޷ʹSTM1 - ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ \ No newline at end of file + ޸gtm pwmռձֻGTM_ATOM0_PWM_DUTY_MAXЧ + +V1.0.2 + ޸ģIICĬʱʱΪ20 + ҪرעP20_2DzģֻĹ ע + ͷɼDMAΪlink䣬Դ󽵵DMAжϴ + ޸ĬϵIICŶ + 6050 ҪõIICģ飬ڳʼĬϵģIICʼ + С \ No newline at end of file diff --git a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/common/common.c b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/common/common.c index 0460d15..ac42b19 100644 --- a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/common/common.c +++ b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/common/common.c @@ -22,7 +22,7 @@ #include "SysSe/Bsp/Bsp.h" #include "common.h" -uint8 camera_type; +uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С diff --git a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/common/common.h b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/common/common.h index fe7ec63..13d03cd 100644 --- a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/common/common.h +++ b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/common/common.h @@ -111,7 +111,7 @@ typedef enum //ö #include -extern uint8 camera_type; +extern uint8 camera_type; //ͷͺ 1 2ͫδ֧֣3С void get_clk(void); diff --git a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/headfile.h b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/headfile.h index 0e8024f..e11bd83 100644 --- a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/headfile.h +++ b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/headfile.h @@ -62,6 +62,7 @@ #include "SEEKFREE_L3G4200D.h" #include "SEEKFREE_WIRELESS.h" #include "SEEKFREE_IPS200_PARALLEL8.h" +#include "SEEKFREE_7725.h" #endif diff --git a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/zf_eru_dma.c b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/zf_eru_dma.c index f7aab10..86c0158 100644 --- a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/zf_eru_dma.c +++ b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/zf_eru_dma.c @@ -21,9 +21,18 @@ #include "IfxDma_Dma.h" #include "IfxScuEru.h" #include "isr_config.h" +#include "zf_assert.h" #include "zf_eru_dma.h" +typedef struct +{ + Ifx_DMA_CH IFX_ALIGN(256) linked_list[8];//DMA + IfxDma_Dma_Channel channel; //DMAͨ +}DMA_LINK; + + +DMA_LINK dma_link_list; //------------------------------------------------------------------------------------------------------------------- // @brief erudmaʼ @@ -36,7 +45,7 @@ // @return void // Sample usage: //------------------------------------------------------------------------------------------------------------------- -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count) { IfxDma_Dma_Channel dmaChn; //eruDMAͨ eruļeruȼΪͨ @@ -51,27 +60,85 @@ void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destinatio IfxDma_Dma_ChannelConfig cfg; IfxDma_Dma_initChannelConfig(&cfg, &dma); - cfg.transferCount = dma_count; + uint8 list_num, i; + uint16 single_channel_dma_count; + + ZF_ASSERT(!(dma_count%8));//Ϊ8ı + + + list_num = 1; + single_channel_dma_count = dma_count / list_num; + if(16384 < single_channel_dma_count) + { + while(TRUE) + { + single_channel_dma_count = dma_count / list_num; + if((single_channel_dma_count <= 16384) && !(dma_count % list_num)) + { + break; + } + list_num++; + if(list_num > 8) ZF_ASSERT(FALSE); + } + } + + + if(1 == list_num) + { + cfg.shadowControl = IfxDma_ChannelShadow_none; + cfg.operationMode = IfxDma_ChannelOperationMode_single; + cfg.shadowAddress = 0; + } + else + { + cfg.shadowControl = IfxDma_ChannelShadow_linkedList; + cfg.operationMode = IfxDma_ChannelOperationMode_continuous; + cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[1]); + } + cfg.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest; cfg.moveSize = IfxDma_ChannelMoveSize_8bit; + cfg.busPriority = IfxDma_ChannelBusPriority_high; - cfg.busPriority = IfxDma_ChannelBusPriority_high; - - cfg.sourceAddress = (unsigned)(source_addr); + cfg.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), source_addr); cfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_none; cfg.sourceCircularBufferEnabled = TRUE; - cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); cfg.destinationAddressIncrementStep = IfxDma_ChannelIncrementStep_1; - cfg.operationMode = IfxDma_ChannelOperationMode_single; - cfg.channelId = (IfxDma_ChannelId)dma_ch; - cfg.hardwareRequestEnabled = TRUE; - cfg.channelInterruptEnabled = TRUE; + cfg.channelId = (IfxDma_ChannelId)dma_ch; + cfg.hardwareRequestEnabled = FALSE; + cfg.channelInterruptEnabled = TRUE; cfg.channelInterruptPriority = ERU_DMA_INT_PRIO; cfg.channelInterruptTypeOfService = (IfxSrc_Tos)ERU_DMA_INT_SERVICE; + + + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr); + + cfg.transferCount = single_channel_dma_count; + IfxDma_Dma_initChannel(&dmaChn, &cfg); + + if(1 < list_num) + { + i = 0; + while(i < list_num) + { + cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr + single_channel_dma_count * i); + if(i == (list_num - 1)) cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[0]); + else cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (unsigned)&dma_link_list.linked_list[i+1]); + cfg.transferCount = single_channel_dma_count; + + IfxDma_Dma_initLinkedListEntry((void *)&dma_link_list.linked_list[i], &cfg); + i++; + } + } + + + IfxDma_Dma_getSrcPointer(&dma_link_list.channel)->B.CLRR = 1; + + return list_num; } diff --git a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/zf_eru_dma.h b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/zf_eru_dma.h index 50667ad..faef169 100644 --- a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/zf_eru_dma.h +++ b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/zf_eru_dma.h @@ -29,9 +29,9 @@ #define CLEAR_DMA_FLAG(dma_ch) IfxDma_clearChannelInterrupt(&MODULE_DMA, dma_ch); -#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)destination_addr) +#define DMA_SET_DESTINATION(dma_ch, destination_addr) IfxDma_setChannelDestinationAddress(&MODULE_DMA, dma_ch, (void *)IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), destination_addr)) -void eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); +uint8 eru_dma_init(IfxDma_ChannelId dma_ch, uint8 *source_addr, uint8 *destination_addr, ERU_PIN_enum eru_pin, TRIGGER_enum trigger, uint16 dma_count); void dma_stop(IfxDma_ChannelId dma_ch); void dma_start(IfxDma_ChannelId dma_ch); diff --git a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/zf_gpio.c b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/zf_gpio.c index 3c937cf..1d2466c 100644 --- a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/zf_gpio.c +++ b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/zf_gpio.c @@ -60,6 +60,7 @@ Ifx_P* get_port(PIN_enum pin) // @param pinmode ãòzf_gpio.hļGPIOMODE_enumöֵȷ // @return void // Sample usage: gpio_init(P00_0, GPO, 1, PUSHPULL);//P00_0ʼΪGPIOܡģʽߵƽ +// @note ҪرעP20_2DzģֻĹ //------------------------------------------------------------------------------------------------------------------- void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinmode) { diff --git a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/zf_gpio.h b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/zf_gpio.h index cfbd666..e3d144f 100644 --- a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/zf_gpio.h +++ b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_libraries/zf_gpio.h @@ -38,6 +38,15 @@ typedef enum // ö #define GET_PORT_IN_ADDR(pin) (uint8 *)(&IfxPort_getAddress((IfxPort_Index)(pin/32))->IN + pin%32/8) + + +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ +//ҪرעP20_2DzģֻĹ + + + + //------------------------------------------------------ //ͨGPIO void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinconf); diff --git a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_7725.c b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_7725.c new file mode 100644 index 0000000..806b8d9 --- /dev/null +++ b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_7725.c @@ -0,0 +1,262 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + +#include "IfxDma.h" +#include "IfxScuEru.h" +#include "zf_stm_systick.h" +#include "zf_gpio.h" +#include "zf_eru.h" +#include "zf_eru_dma.h" +#include "SEEKFREE_IIC.h" +#include "SEEKFREE_7725.h" + + + +IFX_ALIGN(4) uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +uint8 image_dec[OV7725_H][OV7725_W]; + +uint8 ov7725_idcode = 0; + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷڲĴʼ(ڲʹãû) +// @param NULL +// @return uint8 01ɹ +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_reg_init(void) +{ + simiic_delay_set(500); + simiic_write_reg ( OV7725_DEV_ADD, OV7725_COM7, 0x80 ); //λͷ + systick_delay_ms(STM0, 50); + ov7725_idcode = simiic_read_reg( OV7725_DEV_ADD, OV7725_VER ,SCCB); + if( ov7725_idcode != OV7725_ID ) return 0; //УͷID + + //IDȷ ȻüĴ + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM4 , 0xC1); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CLKRC , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM2 , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM3 , 0xD0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM7 , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_COM8 , 0xCE); //0xCE:رԶع 0xCFԶع + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSTART , 0x3F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HSIZE , 0x50); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSTRT , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_VSIZE , 0x78); + simiic_write_reg(OV7725_DEV_ADD, OV7725_HREF , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SCAL0 , 0x0A); + simiic_write_reg(OV7725_DEV_ADD, OV7725_AWB_Ctrl0 , 0xE0); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSPAuto , 0xff); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl2 , 0x0C); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl3 , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_DSP_Ctrl4 , 0x00); + + if(OV7725_W == 80) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x14); + else if(OV7725_W == 160) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x28); + else if(OV7725_W == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x3c); + else if(OV7725_W == 320) simiic_write_reg(OV7725_DEV_ADD, OV7725_HOutSize , 0x50); + + if(OV7725_H == 60) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x1E); + else if(OV7725_H == 120) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x3c); + else if(OV7725_H == 180) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x5a); + else if(OV7725_H == 240) simiic_write_reg(OV7725_DEV_ADD, OV7725_VOutSize , 0x78); + + simiic_write_reg(OV7725_DEV_ADD, OV7725_REG28 , 0x01); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCH , 0x10); + simiic_write_reg(OV7725_DEV_ADD, OV7725_EXHCL , 0x1F); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM1 , 0x0c); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM2 , 0x16); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM3 , 0x2a); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM4 , 0x4e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM5 , 0x61); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM6 , 0x6f); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM7 , 0x7b); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM8 , 0x86); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM9 , 0x8e); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM10 , 0x97); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM11 , 0xa4); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM12 , 0xaf); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM13 , 0xc5); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM14 , 0xd7); + simiic_write_reg(OV7725_DEV_ADD, OV7725_GAM15 , 0xe8); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SLOP , 0x20); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_RADI , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEF , 0x13); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_XC , 0x08); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFB , 0x14); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_COEFR , 0x17); + simiic_write_reg(OV7725_DEV_ADD, OV7725_LC_CTR , 0x05); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDBase , 0x99); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BDMStep , 0x03); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SDE , 0x04); + simiic_write_reg(OV7725_DEV_ADD, OV7725_BRIGHT , 0x00); + simiic_write_reg(OV7725_DEV_ADD, OV7725_CNST , 0x40); + simiic_write_reg(OV7725_DEV_ADD, OV7725_SIGN , 0x06); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ0 , 0x11); + simiic_write_reg(OV7725_DEV_ADD, OV7725_UVADJ1 , 0x02); + + + simiic_delay_set(SIMIIC_DELAY_TIME);//޸ΪĬϵ20 + return 1; + + +} + + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷɼʼ(ڲʹãû) +// @param NULL +// @return void +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +void ov7725_port_init(void) +{ + uint8 i; + camera_type = 3;//ͷ + + //ͷɼʼ + //ʼ + for(i=0; i<8; i++) + { + gpio_init((PIN_enum)(OV7725_DATA_PIN+i), GPI, 0, PULLUP); + } + eru_dma_init(OV7725_DMA_CH, GET_PORT_IN_ADDR(OV7725_DATA_PIN), image_bin[0], OV7725_PCLK_PIN, FALLING, OV7725_DMA_NUM); + eru_init(OV7725_VSYNC_PIN, FALLING); //ʼжϣΪ½شж + +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷʼ(֮úжϺɲɼͼ) +// @param NULL +// @return 0 +// @since v1.0 +// Sample usage: +//------------------------------------------------------------------------------------------------------------------- +uint8 ov7725_init(void) +{ + simiic_init(); + ov7725_reg_init(); //ͷĴ + ov7725_port_init(); //ͷжżDMA + return 0; +} + + + + +uint8 ov7725_finish_flag = 0; +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбeruGPIOжϣжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_vsync(void) +{ + CLEAR_GPIO_FLAG(OV7725_VSYNC_PIN); + + if(!ov7725_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ + { + DMA_SET_DESTINATION(OV7725_DMA_CH, image_bin[0]); + dma_start(OV7725_DMA_CH); + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief СͷDMAж +// @param NULL +// @return void +// @since v1.0 +// Sample usage: ˺isr.cбdmaжϵ +//------------------------------------------------------------------------------------------------------------------- +void ov7725_dma(void) +{ + CLEAR_DMA_FLAG(OV7725_DMA_CH); + ov7725_finish_flag = 1; + dma_stop(OV7725_DMA_CH); +} + + + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷݽѹ +// @param *data1 Դַ +// @param *data2 Ŀĵַ +// @return void +// @since v1.0 +// Sample usage: Image_Decompression(da1,dat2[0]);//һάdat1ݽѹάdat2. +//------------------------------------------------------------------------------------------------------------------- +void image_decompression(uint8 *data1,uint8 *data2) +{ + uint8 temp[2] = {0,255}; + uint16 lenth = OV7725_SIZE; + uint8 i = 8; + + + while(lenth--) + { + i = 8; + while(i--) + { + *data2++ = temp[(*data1 >> i) & 0x01]; + } + data1++; + } +} + + +//------------------------------------------------------------------------------------------------------------------- +// @brief Сͷδѹͼλ鿴ͼ +// @param *imgaddr ѹͼݵַ +// @param *imgsize ͼС(ֱдOV7725_SIZE) +// @return void +// @since v1.0 +// Sample usage: øúǰȳʼuart2 +//------------------------------------------------------------------------------------------------------------------- +void seekfree_sendimg_7725(UARTN_enum uartn) +{ + uart_putchar(uartn, 0x00);uart_putchar(uartn, 0xff);uart_putchar(uartn, 0x01);uart_putchar(uartn, 0x01);//ĸֽ + uart_putbuff(uartn, image_bin[0], OV7725_SIZE); //ٷͼ +} + + + + diff --git a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_7725.h b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_7725.h new file mode 100644 index 0000000..e513250 --- /dev/null +++ b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_7725.h @@ -0,0 +1,243 @@ +/********************************************************************************************************************* + * COPYRIGHT NOTICE + * Copyright (c) 2020,ɿƼ + * All rights reserved. + * QQȺȺ824575535 + * + * ݰȨɿƼУδҵ; + * ӭλʹò޸ʱ뱣ɿƼİȨ + * + * @file main + * @company ɶɿƼ޹˾ + * @author ɿƼ(QQ3184284598) + * @version 鿴docversionļ 汾˵ + * @Software tasking v6.3r1 + * @Target core TC264D + * @Taobao https://seekfree.taobao.com/ + * @date 2020-3-23 + * @note + ߶壺 + ------------------------------------ + ģܽ Ƭܽ + SDA 鿴SEEKFREE_IICļڵSEEKFREE_SDA궨 + SCL 鿴SEEKFREE_IICļڵSEEKFREE_SCL궨 + ж(VSY) 鿴SEEKFREE_OV7725.hļеOV7725_VSYNC_PIN궨 + ж(HREF) δʹã˲ + ж(PCLK) 鿴SEEKFREE_OV7725.hļеOV7725_PCLK_PIN궨 + ݿ(D0-D7) 鿴SEEKFREE_OV7725.hļеOV7725_DATA_PIN궨 + ------------------------------------ + + ĬϷֱ 160*120 + ĬFPS 50֡ + ********************************************************************************************************************/ + + + +#ifndef _SEEKFREE_7725_h +#define _SEEKFREE_7725_h + +#include "common.h" +#include "IfxDma_cfg.h" +#include "zf_uart.h" + + +//ͷID +#define OV7725_ID 0x21 + +//ͷĴ +#define OV7725_GAIN 0x00 +#define OV7725_BLUE 0x01 +#define OV7725_RED 0x02 +#define OV7725_GREEN 0x03 +#define OV7725_BAVG 0x05 +#define OV7725_GAVG 0x06 +#define OV7725_RAVG 0x07 +#define OV7725_AECH 0x08 +#define OV7725_COM2 0x09 +#define OV7725_PID 0x0A +#define OV7725_VER 0x0B +#define OV7725_COM3 0x0C +#define OV7725_COM4 0x0D +#define OV7725_COM5 0x0E +#define OV7725_COM6 0x0F +#define OV7725_AEC 0x10 +#define OV7725_CLKRC 0x11 +#define OV7725_COM7 0x12 +#define OV7725_COM8 0x13 +#define OV7725_COM9 0x14 +#define OV7725_COM10 0x15 +#define OV7725_REG16 0x16 +#define OV7725_HSTART 0x17 +#define OV7725_HSIZE 0x18 +#define OV7725_VSTRT 0x19 +#define OV7725_VSIZE 0x1A +#define OV7725_PSHFT 0x1B +#define OV7725_MIDH 0x1C +#define OV7725_MIDL 0x1D +#define OV7725_LAEC 0x1F +#define OV7725_COM11 0x20 +#define OV7725_BDBase 0x22 +#define OV7725_BDMStep 0x23 +#define OV7725_AEW 0x24 +#define OV7725_AEB 0x25 +#define OV7725_VPT 0x26 +#define OV7725_REG28 0x28 +#define OV7725_HOutSize 0x29 +#define OV7725_EXHCH 0x2A +#define OV7725_EXHCL 0x2B +#define OV7725_VOutSize 0x2C +#define OV7725_ADVFL 0x2D +#define OV7725_ADVFH 0x2E +#define OV7725_YAVE 0x2F +#define OV7725_LumHTh 0x30 +#define OV7725_LumLTh 0x31 +#define OV7725_HREF 0x32 +#define OV7725_DM_LNL 0x33 +#define OV7725_DM_LNH 0x34 +#define OV7725_ADoff_B 0x35 +#define OV7725_ADoff_R 0x36 +#define OV7725_ADoff_Gb 0x37 +#define OV7725_ADoff_Gr 0x38 +#define OV7725_Off_B 0x39 +#define OV7725_Off_R 0x3A +#define OV7725_Off_Gb 0x3B +#define OV7725_Off_Gr 0x3C +#define OV7725_COM12 0x3D +#define OV7725_COM13 0x3E +#define OV7725_COM14 0x3F +#define OV7725_COM16 0x41 +#define OV7725_TGT_B 0x42 +#define OV7725_TGT_R 0x43 +#define OV7725_TGT_Gb 0x44 +#define OV7725_TGT_Gr 0x45 +#define OV7725_LC_CTR 0x46 +#define OV7725_LC_XC 0x47 +#define OV7725_LC_YC 0x48 +#define OV7725_LC_COEF 0x49 +#define OV7725_LC_RADI 0x4A +#define OV7725_LC_COEFB 0x4B +#define OV7725_LC_COEFR 0x4C +#define OV7725_FixGain 0x4D +#define OV7725_AREF1 0x4F +#define OV7725_AREF6 0x54 +#define OV7725_UFix 0x60 +#define OV7725_VFix 0x61 +#define OV7725_AWBb_blk 0x62 +#define OV7725_AWB_Ctrl0 0x63 +#define OV7725_DSP_Ctrl1 0x64 +#define OV7725_DSP_Ctrl2 0x65 +#define OV7725_DSP_Ctrl3 0x66 +#define OV7725_DSP_Ctrl4 0x67 +#define OV7725_AWB_bias 0x68 +#define OV7725_AWBCtrl1 0x69 +#define OV7725_AWBCtrl2 0x6A +#define OV7725_AWBCtrl3 0x6B +#define OV7725_AWBCtrl4 0x6C +#define OV7725_AWBCtrl5 0x6D +#define OV7725_AWBCtrl6 0x6E +#define OV7725_AWBCtrl7 0x6F +#define OV7725_AWBCtrl8 0x70 +#define OV7725_AWBCtrl9 0x71 +#define OV7725_AWBCtrl10 0x72 +#define OV7725_AWBCtrl11 0x73 +#define OV7725_AWBCtrl12 0x74 +#define OV7725_AWBCtrl13 0x75 +#define OV7725_AWBCtrl14 0x76 +#define OV7725_AWBCtrl15 0x77 +#define OV7725_AWBCtrl16 0x78 +#define OV7725_AWBCtrl17 0x79 +#define OV7725_AWBCtrl18 0x7A +#define OV7725_AWBCtrl19 0x7B +#define OV7725_AWBCtrl20 0x7C +#define OV7725_AWBCtrl21 0x7D +#define OV7725_GAM1 0x7E +#define OV7725_GAM2 0x7F +#define OV7725_GAM3 0x80 +#define OV7725_GAM4 0x81 +#define OV7725_GAM5 0x82 +#define OV7725_GAM6 0x83 +#define OV7725_GAM7 0x84 +#define OV7725_GAM8 0x85 +#define OV7725_GAM9 0x86 +#define OV7725_GAM10 0x87 +#define OV7725_GAM11 0x88 +#define OV7725_GAM12 0x89 +#define OV7725_GAM13 0x8A +#define OV7725_GAM14 0x8B +#define OV7725_GAM15 0x8C +#define OV7725_SLOP 0x8D +#define OV7725_DNSTh 0x8E +#define OV7725_EDGE0 0x8F +#define OV7725_EDGE1 0x90 +#define OV7725_DNSOff 0x91 +#define OV7725_EDGE2 0x92 +#define OV7725_EDGE3 0x93 +#define OV7725_MTX1 0x94 +#define OV7725_MTX2 0x95 +#define OV7725_MTX3 0x96 +#define OV7725_MTX4 0x97 +#define OV7725_MTX5 0x98 +#define OV7725_MTX6 0x99 +#define OV7725_MTX_Ctrl 0x9A +#define OV7725_BRIGHT 0x9B +#define OV7725_CNST 0x9C +#define OV7725_UVADJ0 0x9E +#define OV7725_UVADJ1 0x9F +#define OV7725_SCAL0 0xA0 +#define OV7725_SCAL1 0xA1 +#define OV7725_SCAL2 0xA2 +#define OV7725_SDE 0xA6 +#define OV7725_USAT 0xA7 +#define OV7725_VSAT 0xA8 +#define OV7725_HUECOS 0xA9 +#define OV7725_HUESIN 0xAA +#define OV7725_SIGN 0xAB +#define OV7725_DSPAuto 0xAC + + +#define OV7725_DEV_ADD 0x42>>1 + + +//ͷ +#define OV7725_W 160 //ͷͼ ò 80 160 240 320 +#define OV7725_H 120 //ͷͼ߶ ò 60 120 180 240 +#define OV7725_SIZE (OV7725_W * OV7725_H/8 ) //ͼռÿռС +#define OV7725_DMA_NUM (OV7725_SIZE) //һͼDMAɼ + + +//-------------------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------------------- +#define OV7725_VSYNC_PIN ERU_CH3_REQ6_P02_0 //ж ѡΧοERU_PIN_enumö ѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DATA_PIN P00_0 //D0 D0ΪP00_0 ôD1ʹõΪP00_1 + //òP00_0P02_0P15_0Ϊ + +#define OV7725_PCLK_PIN ERU_CH2_REQ14_P02_1 //ʱ ѡΧοERU_PIN_enumö 볡жѡΪͬһͨǹжϵͨ + //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ + +#define OV7725_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ + //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 + + + +extern uint8 image_bin[OV7725_H][OV7725_W/8]; //洢ͼ +extern uint8 image_dec[OV7725_H][OV7725_W]; //ͼѹ + +extern uint8 ov7725_finish_flag; //ͼɼɱ־λ + + +// +uint8 ov7725_init(void); +void ov7725_vsync(void); +void ov7725_dma(void); +void image_decompression(uint8 *data1,uint8 *data2); +void seekfree_sendimg_7725(UARTN_enum uartn); + + + +#endif + + + diff --git a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c index 095f9e3..5d167c9 100644 --- a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c +++ b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_ICM20602.c @@ -68,6 +68,7 @@ void icm20602_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void icm20602_init(void) { + simiic_init(); systick_delay_ms(STM0, 10); //ϵʱ // diff --git a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_IIC.c b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_IIC.c index 196fd57..f56a41a 100644 --- a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_IIC.c +++ b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_IIC.c @@ -50,7 +50,7 @@ uint8 IIC_num; // -static uint16 simiic_delay_time=100; //ICMȴӦΪ100 +static uint16 simiic_delay_time = SIMIIC_DELAY_TIME; //ICMȴӦΪ20 //------------------------------------------------------------------------------------------------------------------- diff --git a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_IIC.h b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_IIC.h index 293a02a..6a9c1e3 100644 --- a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_IIC.h +++ b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_IIC.h @@ -34,8 +34,12 @@ -#define SEEKFREE_SCL P13_0 //SCL ΪIO -#define SEEKFREE_SDA P13_1 //SDA ΪIO +#define SEEKFREE_SCL P02_3 //SCL ΪIO +#define SEEKFREE_SDA P02_2 //SDA ΪIO + + +#define SIMIIC_DELAY_TIME 20 + typedef enum IIC //DACģ { diff --git a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c index 0f0c23a..5deb7d3 100644 --- a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c +++ b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_L3G4200D.c @@ -65,6 +65,7 @@ void l3g4200d_self_check(void) //------------------------------------------------------------------------------------------------------------------- void l3g4200d_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); l3g4200d_self_check(); diff --git a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c index c200427..8a5eec4 100644 --- a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c +++ b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_MMA8451.c @@ -68,6 +68,7 @@ void mma8451_self_check(void) //------------------------------------------------------------------------------------------------------------------- uint8 mma845x_init(void) { + simiic_init(); systick_delay_ms(STM0, 50); mma8451_self_check(); diff --git a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c index 0317aa0..686550d 100644 --- a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c +++ b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_MPU6050.c @@ -71,6 +71,7 @@ void mpu6050_self1_check(void) //------------------------------------------------------------------------------------------------------------------- void mpu6050_init(void) { + simiic_init(); systick_delay_ms(STM0, 100); //ϵʱ mpu6050_self1_check(); diff --git a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c index 014b435..05f181f 100644 --- a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c +++ b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c @@ -38,7 +38,6 @@ #include "zf_gpio.h" #include "zf_eru.h" #include "zf_eru_dma.h" -#include "stdio.h" #include "SEEKFREE_MT9V03X.h" @@ -49,6 +48,8 @@ uint8 receive[3]; uint8 receive_num = 0; vuint8 uart_receive_flag; +uint8 link_list_num; + //Ҫõͷ int16 MT9V03X_CFG[CONFIG_FINISH][2]= { @@ -305,7 +306,7 @@ void mt9v03x_init(void) gpio_init((PIN_enum)(MT9V03X_DATA_PIN+i), GPI, 0, PULLUP); } - eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W); + link_list_num = eru_dma_init(MT9V03X_DMA_CH, GET_PORT_IN_ADDR(MT9V03X_DATA_PIN), mt9v03x_image[0], MT9V03X_PCLK_PIN, RISING, MT9V03X_W*MT9V03X_H); eru_init(MT9V03X_VSYNC_PIN, FALLING); //ʼжϣΪ½شж restoreInterrupts(interrupt_state); @@ -313,7 +314,6 @@ void mt9v03x_init(void) uint8 mt9v03x_finish_flag = 0; //һͼɼɱ־λ -uint8 now_col; //ǰڲɼ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03Xͷж // @param NULL @@ -324,16 +324,15 @@ uint8 now_col; // void mt9v03x_vsync(void) { CLEAR_GPIO_FLAG(MT9V03X_VSYNC_PIN); - now_col = 0; + if(!mt9v03x_finish_flag)//鿴ͼǷʹϣδʹ򲻿ʼɼַʳͻ { - DMA_SET_DESTINATION(MT9V03X_DMA_CH, (void *)&mt9v03x_image[0]); dma_start(MT9V03X_DMA_CH); } } - +uint8 mt9v03x_dma_int_num; //ǰDMAжϴ //------------------------------------------------------------------------------------------------------------------- // @brief MT9V03XͷDMAж // @param NULL @@ -344,16 +343,15 @@ void mt9v03x_vsync(void) void mt9v03x_dma(void) { CLEAR_DMA_FLAG(MT9V03X_DMA_CH); + mt9v03x_dma_int_num++; - now_col++; - - if(MT9V03X_H > now_col) - { - dma_start(MT9V03X_DMA_CH); - } - else + if(mt9v03x_dma_int_num >= link_list_num) { + //ɼ + mt9v03x_dma_int_num = 0; mt9v03x_finish_flag = 1;//һͼӲɼʼɼʱ3.8MS(50FPS188*120ֱ) + dma_stop(MT9V03X_DMA_CH); + } } diff --git a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h index a29edd2..0c8a785 100644 --- a/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h +++ b/Seekfree_TC264_Opensource_Library/Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.h @@ -63,9 +63,7 @@ //糡жѡERU_CH3 ôžͲѡERU_CH7Ϊ37жǹõġ #define MT9V03X_DMA_CH IfxDma_ChannelId_5 //ʹõDMAͨ 0-47ѡ ͨԽȼԽ - //޸Ĵ˴֮Ҫ޸ĶӦERUжȼ˴ΪIfxDma_ChannelId_5ӦERUжȼӦΪ5 - - + //ͷö typedef enum { diff --git a/Seekfree_TC264_Opensource_Library/USER/Cpu0_Main.c b/Seekfree_TC264_Opensource_Library/USER/Cpu0_Main.c index 486ec0e..ba8554a 100644 --- a/Seekfree_TC264_Opensource_Library/USER/Cpu0_Main.c +++ b/Seekfree_TC264_Opensource_Library/USER/Cpu0_Main.c @@ -26,7 +26,6 @@ int core0_main(void) get_clk();//ȡʱƵ ر //ûڴ˴øֳʼ - enableInterrupts(); while (TRUE) diff --git a/Seekfree_TC264_Opensource_Library/USER/isr.c b/Seekfree_TC264_Opensource_Library/USER/isr.c index 15666f2..c6376b0 100644 --- a/Seekfree_TC264_Opensource_Library/USER/isr.c +++ b/Seekfree_TC264_Opensource_Library/USER/isr.c @@ -98,7 +98,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) if(GET_GPIO_FLAG(ERU_CH3_REQ6_P02_0))//ͨ3ж { CLEAR_GPIO_FLAG(ERU_CH3_REQ6_P02_0); - if(1 == camera_type)mt9v03x_vsync(); + if (1 == camera_type) mt9v03x_vsync(); + else if (3 == camera_type) ov7725_vsync(); } if(GET_GPIO_FLAG(ERU_CH7_REQ16_P15_1))//ͨ7ж @@ -113,7 +114,8 @@ IFX_INTERRUPT(eru_ch3_ch7_isr, ERU_CH3_CH7_INT_SERVICE, ERU_CH3_CH7_INT_PRIO) IFX_INTERRUPT(dma_ch5_isr, ERU_DMA_INT_SERVICE, ERU_DMA_INT_PRIO) { - if(1 == camera_type) mt9v03x_dma(); + if (1 == camera_type) mt9v03x_dma(); + else if (3 == camera_type) ov7725_dma(); } diff --git a/【文档】TASKING使用教程 芯片手册等/逐飞科技 TASKING使用说明书 V1.0.pdf b/【文档】TASKING使用教程 芯片手册等/逐飞科技 TASKING使用说明书 V1.0.pdf deleted file mode 100644 index dc27b3c06c1974a5e6d7f56b5e3641d973443aae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1480522 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�qj6l{D`?>9615`kH96%J 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

    @v06P{0k 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

    #EZ~Oy+vn^wuRI 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%0DoL%fwIe=w8tqP|+BC91r2H>-1c^?EQ)S9> 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]ydDj*Gk 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

    AB*Q>}`~NhmwU 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

    jhY)%3YfOqrSdRXJ1 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