| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577 |
- /*
- * Copyright (c) 2022 OpenLuat & AirM2M
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- #include "user.h"
- #include "zbar.h"
- #include "symbol.h"
- #include "image.h"
- #if 1
- #define CAMERA_WIDTH 320
- #define CAMERA_HEIGHT 240
- #else
- #define CAMERA_WIDTH 160
- #define CAMERA_HEIGHT 80
- #endif
- #define GC032A_I2C_ADDRESS 0x21
- #define OV2640_I2C_ADDRESS 0x30
- static const I2C_CommonRegDataStruct GC032A_InitRegQueue[] =
- {
- {0xf3, 0xff},
- {0xf7, 0x01},
- {0xf8, 0x03},
- {0xf9, 0xce},
- {0xfa, 0x00},
- {0xfc, 0x02},
- {0xfe, 0x02},
- {0x81, 0x03},
- {0xfe,0x00},
- {0x03,0x01},
- {0x04,0xc2},
- {0x05,0x01},
- {0x06,0xc2},
- {0x07,0x00},
- {0x08,0x08},
- {0x0a,0x04},
- {0x0c,0x04},
- {0x0d,0x01},
- {0x0e,0xe8},
- {0x0f,0x02},
- {0x10,0x88},
- //{0x17,0x55},
- {0x17,0x54},
- {0x19,0x04},
- {0x1a,0x0a},
- {0x1f,0x40},
- {0x20,0x30},
- {0x2e,0x80},
- {0x2f,0x2b},
- {0x30,0x1a},
- {0xfe,0x02},
- {0x03,0x02},
- {0x06,0x60},
- {0x05,0xd7},
- {0x12,0x89},
- {0xfe,0x00},
- {0x18,0x02},
- {0xfe,0x02},
- {0x40,0x22},
- {0x45,0x00},
- {0x46,0x00},
- {0x49,0x20},
- {0xfe,0x01},
- {0x0a,0xc5},
- {0x45,0x00},
- {0xfe,0x00},
- {0x40,0xff},
- {0x41,0x25},
- {0x42,0x83},
- {0x43,0x10},
- {0x46,0x26},
- {0x49,0x03},
- {0x4f,0x01},
- {0xde,0x84},
- {0xfe,0x02},
- {0x22,0xf6},
- {0xfe,0x01},
- {0x12,0xa0},
- {0x13,0x3a},
- {0xc1,0x3c},
- {0xc2,0x50},
- {0xc3,0x00},
- {0xc4,0x32},
- {0xc5,0x24},
- {0xc6,0x16},
- {0xc7,0x08},
- {0xc8,0x08},
- {0xc9,0x00},
- {0xca,0x20},
- {0xdc,0x8a},
- {0xdd,0xa0},
- {0xde,0xa6},
- {0xdf,0x75},
- {0xfe,0x01},
- {0x7c,0x09},
- {0x65,0x00},
- {0x7c,0x08},
- {0x56,0xf4},
- {0x66,0x0f},
- {0x67,0x84},
- {0x6b,0x80},
- {0x6d,0x12},
- {0x6e,0xb0},
- {0x86,0x00},
- {0x87,0x00},
- {0x88,0x00},
- {0x89,0x00},
- {0x8a,0x00},
- {0x8b,0x00},
- {0x8c,0x00},
- {0x8d,0x00},
- {0x8e,0x00},
- {0x8f,0x00},
- {0x90,0xef},
- {0x91,0xe1},
- {0x92,0x0c},
- {0x93,0xef},
- {0x94,0x65},
- {0x95,0x1f},
- {0x96,0x0c},
- {0x97,0x2d},
- {0x98,0x20},
- {0x99,0xaa},
- {0x9a,0x3f},
- {0x9b,0x2c},
- {0x9c,0x5f},
- {0x9d,0x3e},
- {0x9e,0xaa},
- {0x9f,0x67},
- {0xa0,0x60},
- {0xa1,0x00},
- {0xa2,0x00},
- {0xa3,0x0a},
- {0xa4,0xb6},
- {0xa5,0xac},
- {0xa6,0xc1},
- {0xa7,0xac},
- {0xa8,0x55},
- {0xa9,0xc3},
- {0xaa,0xa4},
- {0xab,0xba},
- {0xac,0xa8},
- {0xad,0x55},
- {0xae,0xc8},
- {0xaf,0xb9},
- {0xb0,0xd4},
- {0xb1,0xc3},
- {0xb2,0x55},
- {0xb3,0xd8},
- {0xb4,0xce},
- {0xb5,0x00},
- {0xb6,0x00},
- {0xb7,0x05},
- {0xb8,0xd6},
- {0xb9,0x8c},
- {0xfe,0x01},
- {0xd0,0x40},
- {0xd1,0xf8},
- {0xd2,0x00},
- {0xd3,0xfa},
- {0xd4,0x45},
- {0xd5,0x02},
- {0xd6,0x30},
- {0xd7,0xfa},
- {0xd8,0x08},
- {0xd9,0x08},
- {0xda,0x58},
- {0xdb,0x02},
- {0xfe,0x00},
- {0xfe,0x00},
- {0xba,0x00},
- {0xbb,0x04},
- {0xbc,0x0a},
- {0xbd,0x0e},
- {0xbe,0x22},
- {0xbf,0x30},
- {0xc0,0x3d},
- {0xc1,0x4a},
- {0xc2,0x5d},
- {0xc3,0x6b},
- {0xc4,0x7a},
- {0xc5,0x85},
- {0xc6,0x90},
- {0xc7,0xa5},
- {0xc8,0xb5},
- {0xc9,0xc2},
- {0xca,0xcc},
- {0xcb,0xd5},
- {0xcc,0xde},
- {0xcd,0xea},
- {0xce,0xf5},
- {0xcf,0xff},
- {0xfe,0x00},
- {0x5a,0x08},
- {0x5b,0x0f},
- {0x5c,0x15},
- {0x5d,0x1c},
- {0x5e,0x28},
- {0x5f,0x36},
- {0x60,0x45},
- {0x61,0x51},
- {0x62,0x6a},
- {0x63,0x7d},
- {0x64,0x8d},
- {0x65,0x98},
- {0x66,0xa2},
- {0x67,0xb5},
- {0x68,0xc3},
- {0x69,0xcd},
- {0x6a,0xd4},
- {0x6b,0xdc},
- {0x6c,0xe3},
- {0x6d,0xf0},
- {0x6e,0xf9},
- {0x6f,0xff},
- {0xfe,0x00},
- {0x70,0x50},
- {0xfe,0x00},
- {0x4f,0x01},
- {0xfe,0x01},
- {0x44,0x04},
- {0x1f,0x30},
- {0x20,0x40},
- {0x26,0x9a},
- {0x27,0x02},
- {0x28,0x0d},
- {0x29,0x02},
- {0x2a,0x0d},
- {0x2b,0x02},
- {0x2c,0x58},
- {0x2d,0x07},
- {0x2e,0xd2},
- {0x2f,0x0b},
- {0x30,0x6e},
- {0x31,0x0e},
- {0x32,0x70},
- {0x33,0x12},
- {0x34,0x0c},
- {0x3c,0x20},
- {0x3e,0x20},
- {0x3f,0x2d},
- {0x40,0x40},
- {0x41,0x5b},
- {0x42,0x82},
- {0x43,0xb7},
- {0x04,0x0a},
- {0x02,0x79},
- {0x03,0xc0},
- {0xcc,0x08},
- {0xcd,0x08},
- {0xce,0xa4},
- {0xcf,0xec},
- {0xfe,0x00},
- {0x81,0xb8},
- {0x82,0x12},
- {0x83,0x0a},
- {0x84,0x01},
- {0x86,0x25},
- {0x87,0x18},
- {0x88,0x10},
- {0x89,0x70},
- {0x8a,0x20},
- {0x8b,0x10},
- {0x8c,0x08},
- {0x8d,0x0a},
- {0xfe,0x00},
- {0x8f,0xaa},
- {0x90,0x9c},
- {0x91,0x52},
- {0x92,0x03},
- {0x93,0x03},
- {0x94,0x08},
- {0x95,0x44},
- {0x97,0x00},
- {0x98,0x00},
- {0xfe,0x00},
- {0xa1,0x30},
- {0xa2,0x41},
- {0xa4,0x30},
- {0xa5,0x20},
- {0xaa,0x30},
- {0xac,0x32},
- {0xfe,0x00},
- {0xd1,0x3c},
- {0xd2,0x3c},
- {0xd3,0x38},
- {0xd6,0xf4},
- {0xd7,0x1d},
- {0xdd,0x73},
- {0xde,0x84},
- {0xfe,0x01},
- {0x13,0x20},
- {0xfe,0x00},
- {0x4f,0x00},
- {0x03,0x00},
- {0x04,0xa0},
- {0x71,0x60},
- {0x72,0x40},
- {0x42,0x80},
- {0x77,0x64},
- {0x78,0x40},
- {0x79,0x60},
- {0xfe, 0x00},
- // {0x44, 0x06}, //改成RGB565输出
- {0x44,0x90}, //输出灰度
- {0x46, 0x0f}, //决定了VSYNC,HSYNC, pixclk
- };
- enum
- {
- DECODE_DONE = USER_EVENT_ID_START + 100,
- };
- typedef struct
- {
- HANDLE NotifyTaskHandler;
- uint8_t TestBuf[4096];
- uint8_t *DataCache;
- uint32_t TotalSize;
- uint32_t CurSize;
- uint16_t Width;
- uint16_t Height;
- uint8_t DataBytes;
- uint8_t IsDecode;
- uint8_t BufferFull;
- }QR_DecodeCtrlStruct;
- static QR_DecodeCtrlStruct prvDecodeQR;
- static int32_t prvCamera_DCMICB(void *pData, void *pParam)
- {
- Buffer_Struct *RxBuf = (Buffer_Struct *)pData;
- if (!pData)
- {
- if (!prvDecodeQR.DataCache)
- {
- prvDecodeQR.DataCache = malloc(prvDecodeQR.TotalSize);
- prvDecodeQR.BufferFull = 0;
- }
- else
- {
- if (prvDecodeQR.TotalSize != prvDecodeQR.CurSize)
- {
- // DBG_ERR("%d, %d", prvDecodeQR.CurSize, prvDecodeQR.TotalSize);
- }
- else if (!prvDecodeQR.IsDecode)
- {
- prvDecodeQR.IsDecode = 1;
- Task_SendEvent(prvDecodeQR.NotifyTaskHandler, DECODE_DONE, prvDecodeQR.DataCache, 0, 0);
- prvDecodeQR.DataCache = malloc(prvDecodeQR.TotalSize);
- prvDecodeQR.BufferFull = 0;
- }
- else
- {
- prvDecodeQR.BufferFull = 1;
- }
- }
- prvDecodeQR.CurSize = 0;
- return 0;
- }
- if (prvDecodeQR.DataCache)
- {
- if (prvDecodeQR.BufferFull)
- {
- if (!prvDecodeQR.IsDecode)
- {
- prvDecodeQR.IsDecode = 1;
- Task_SendEvent(prvDecodeQR.NotifyTaskHandler, DECODE_DONE, prvDecodeQR.DataCache, 0, 0);
- prvDecodeQR.DataCache = malloc(prvDecodeQR.TotalSize);
- prvDecodeQR.BufferFull = 0;
- prvDecodeQR.CurSize = 0;
- }
- else
- {
- return 0;
- }
- }
- }
- else
- {
- prvDecodeQR.DataCache = malloc(prvDecodeQR.TotalSize);
- prvDecodeQR.BufferFull = 0;
- prvDecodeQR.CurSize = 0;
- }
- memcpy(&prvDecodeQR.DataCache[prvDecodeQR.CurSize], RxBuf->Data, RxBuf->MaxLen * 4);
- prvDecodeQR.CurSize += RxBuf->MaxLen * 4;
- if (prvDecodeQR.TotalSize < prvDecodeQR.CurSize)
- {
- DBG_ERR("%d,%d", prvDecodeQR.TotalSize, prvDecodeQR.CurSize);
- prvDecodeQR.CurSize = 0;
- }
- return 0;
- }
- static int32_t prvTest_VUartCB(void *pData, void *pParam)
- {
- uint32_t UartID = (uint32_t)pData;
- uint32_t State = (uint32_t)pParam;
- uint16_t ReadLen;
- switch (State)
- {
- case UART_CB_TX_BUFFER_DONE:
- case UART_CB_TX_ALL_DONE:
- // DBG("usb send ok");
- // Core_PrintMemInfo();
- break;
- case UART_CB_RX_BUFFER_FULL:
- case UART_CB_RX_TIMEOUT:
- case UART_CB_RX_NEW:
- ReadLen = Core_VUartRxBufferRead(UartID, prvDecodeQR.TestBuf, sizeof(prvDecodeQR.TestBuf));
- Core_VUartBufferTx(UartID, prvDecodeQR.TestBuf, ReadLen);
- break;
- case UART_CB_ERROR:
- DBG("usb disconnect");
- Core_VUartBufferTxStop(UartID); //也可以选择不清除,USB连上后,会自动重发,但是会有重复发送的情况,需要用户去处理
- break;
- case UART_CB_CONNECTED:
- break;
- }
- }
- static int32_t prvTest_VHIDCB(void *pData, void *pParam)
- {
- uint32_t USB_ID = (uint32_t)pData;
- uint32_t State = (uint32_t)pParam;
- uint16_t ReadLen;
- switch (State)
- {
- case USB_HID_NOT_READY:
- case USB_HID_READY:
- case USB_HID_SEND_DONE:
- DBG("%d", State);
- break;
- }
- }
- static void zbar_task(void *pData)
- {
- OS_EVENT Event;
- unsigned int len;
- int ret;
- char *string;
- zbar_t *zbar;
- LCD_DrawStruct *draw;
- Core_VUartInit(VIRTUAL_UART0, 0, 1, 0, 0, 0, prvTest_VUartCB);
- Core_VHIDInit(USB_ID0, prvTest_VHIDCB);
- while (1) {
- Task_GetEvent(prvDecodeQR.NotifyTaskHandler, DECODE_DONE, &Event, NULL, 0);
- draw = zalloc(sizeof(LCD_DrawStruct));
- draw->Mode = SPI_MODE_0;
- draw->Speed = 48000000;
- draw->SpiID = HSPI_ID0;
- draw->CSPin = GPIOC_14;
- draw->DCPin = 72;
- draw->x1 = 0;
- draw->x2 = prvDecodeQR.Width - 1;
- draw->y1 = 0;
- draw->y2 = prvDecodeQR.Height - 1;
- draw->xoffset = 0;
- draw->yoffset = 0;
- draw->Size = prvDecodeQR.TotalSize;
- draw->ColorMode = COLOR_MODE_GRAY;
- draw->Data = Event.Param1;
- Core_CameraDraw(draw);
- zbar = zbar_create();
- ret = zbar_run(zbar, prvDecodeQR.Width, prvDecodeQR.Height, Event.Param1);
- if (ret > 0)
- {
- string = zbar_get_data_ptr(zbar, &len);
- memcpy(prvDecodeQR.TestBuf, string, len);
- Core_VUartBufferTx(VIRTUAL_UART0, prvDecodeQR.TestBuf, len);
- DBG("%.*s", len, string);
- // Core_PrintMemInfo();
- Core_VHIDUploadData(USB_ID0, string, len);
- }
- zbar_destory(zbar);
- free(Event.Param1);
- prvDecodeQR.IsDecode = 0;
- }
- }
- void DecodeQR_TestInit(void)
- {
- uint8_t Reg = 0xf0;
- uint8_t Data[2];
- uint32_t i;
- prvDecodeQR.DataCache = NULL;
- prvDecodeQR.Width = CAMERA_WIDTH;
- prvDecodeQR.Height = CAMERA_HEIGHT;
- prvDecodeQR.TotalSize = prvDecodeQR.Width * prvDecodeQR.Height;
- prvDecodeQR.DataBytes = 1;
- prvDecodeQR.NotifyTaskHandler = Task_Create(zbar_task, NULL, 8 * 1024, 1, "test zbar");
- GPIO_Config(GPIOD_06, 0, 0);
- GPIO_Config(GPIOD_07, 0, 0);
- // GPIO_ExtiSetHWTimerCB(GC032A_IOCB, NULL);
- GPIO_Iomux(GPIOE_01, 3);
- GPIO_Iomux(GPIOE_02, 3);
- GPIO_Iomux(GPIOE_03, 3);
- GPIO_Iomux(GPIOD_01, 3);
- GPIO_Iomux(GPIOD_02, 3);
- GPIO_Iomux(GPIOD_03, 3);
- GPIO_Iomux(GPIOD_08, 3);
- GPIO_Iomux(GPIOD_09, 3);
- GPIO_Iomux(GPIOD_10, 3);
- GPIO_Iomux(GPIOD_11, 3);
- GPIO_Iomux(GPIOE_00, 3);
- GPIO_Iomux(GPIOE_06, 2);
- GPIO_Iomux(GPIOE_07, 2);
- GPIO_Iomux(GPIOA_05, 2);
- // GPIO_Config(GPIOE_03, 1, 1);
- // GPIO_ExtiConfig(GPIOE_03, 0, 1, 0);
- HWTimer_SetPWM(HW_TIMER5, 24000000, 0, 0);
- Task_DelayMS(1);
- GPIO_Output(GPIOD_06, 1);
- GPIO_Output(GPIOD_07, 1);
- Task_DelayUS(10);
- GPIO_Output(GPIOD_07, 0);
- I2C_MasterSetup(I2C_ID0, 400000);
- Data[0] = 0xf4;
- Data[1] = 0x10;
- I2C_BlockWrite(I2C_ID0, GC032A_I2C_ADDRESS, Data, 2, 10, NULL, 0);
- I2C_BlockRead(I2C_ID0, GC032A_I2C_ADDRESS, &Reg, 1, Data, 2, 10, NULL, 0);
- if ((0x23 == Data[0]) && (0x2a == Data[1]))
- {
- DBG("识别到GC032A控制芯片");
- }
- else
- {
- DBG("没有识别到GC032A控制芯片");
- return;
- }
- // Data[0] = 0xfe;
- // Data[1] = 0x00;
- // Reg = 0x44;
- // I2C_BlockWrite(I2C_ID0, GC032A_I2C_ADDRESS, Data, 2, 10, NULL, 0);
- // I2C_BlockRead(I2C_ID0, GC032A_I2C_ADDRESS, &Reg, Data, 2, 10, NULL, 0);
- // DBG("%x,%x", Data[0], Data[1]);
- for(i = 0; i < sizeof(GC032A_InitRegQueue)/sizeof(I2C_CommonRegDataStruct); i++)
- {
- I2C_BlockWrite(I2C_ID0, GC032A_I2C_ADDRESS, GC032A_InitRegQueue[i].Data, 2, 10, NULL, 0);
- }
- // DBG("GC032A Init Done");
- // I2C_Prepare(I2C_ID0, GC032A_I2C_ADDRESS, 1, GC032A_InitDone, 0);
- // I2C_MasterWriteRegQueue(I2C_ID0, GC032A_InitRegQueue, sizeof(GC032A_InitRegQueue)/sizeof(I2C_CommonRegDataStruct), 10, 0);
- DCMI_Setup(0, 0, 0, 8, 0);
- DCMI_SetCallback(prvCamera_DCMICB, 0);
- DCMI_SetCROPConfig(1, (480-prvDecodeQR.Height)/2, ((640-prvDecodeQR.Width)/2)*prvDecodeQR.DataBytes, prvDecodeQR.Height - 1, prvDecodeQR.DataBytes*prvDecodeQR.Width - 1); //裁剪中间的240*320图像
- DCMI_CaptureSwitch(1, (prvDecodeQR.Width * prvDecodeQR.DataBytes * prvDecodeQR.Height) / 80, 0, 0, 0, NULL); //240 * 2 / 4 * 12,一次DMA传输有12行数据,一共传输20次
- }
|