cis001v2

main.cpp

Committer:
thomashaine
Date:
2021-01-05
Revision:
6:b544e474f959
Parent:
5:2a13bec5f9a3
Child:
7:4c77f017b4b8

File content as of revision 6:b544e474f959:

/* Includes ------------------------------------------------------------------*/
//my include
#include "main.h"
#include "common_task.h"
#include "register_address.h"


//mbed include
#include "stm32h7xx_hal.h"
#include "mbed.h"
#include "EthernetInterface.h"
#include "TCPServer.h"
#include "TCPSocket.h"
//#include "FastPWM.h"


/* Private variables ---------------------------------------------------------*/

//DCMI & DMA stuff
DCMI_HandleTypeDef hdcmi;
DMA_HandleTypeDef hdma_dcmi;

// Virtual USB Serial port
Serial pc(USBTX, USBRX);

// etherner stuff
EthernetInterface eth;

TCPSocket socket;  //data socket
TCPSocket cs;  //com sockey

char ServerIP[17]="10.10.130.12";
int portnumber = 61477;
int portnumber_com = 61478;
char* commandbuffer;
char* commandbuffertemp;


int MSG_LEN=64;


// SPI1
SPI spi(PD_7, PB_4, PA_5); // mosi, miso, sclk
DigitalOut SSN(PA_15);


//LEDs
DigitalOut led1(LED1);  //PB_0
DigitalOut led2(LED2);  //PB7
DigitalOut led3(LED3);  //PB14

    
// GPIOS
DigitalOut RSTN(PA_0); 
DigitalOut SLEEPN(PA_2); 
DigitalOut CAPTURE(PA_9);
InterruptIn button_capture(PC_13);
InterruptIn irq_cis(PA_11);         //TODO
DigitalOut CONFIG1(PA_8);           //TODO
DigitalOut CONFIG2(PD_2);           //TODO
//FastPWM MCLK(PA_3);         


//keep track fo the number of line and frame read
int line_read=0;
int frame_read=0;
int imSize=frame_bsize_10b;

// frame pointer and frame size
char* FRAME_BUFFER;

int DEBUG=1;



/***********************************************************************************************
*
*       Ethernet function
*
************************************************************************************************/

/**
@param none
@return  void
@brief print the start of the frame stored in frame buffer
*/

void print_start_frame(){
    int i,j,k=0;
    int byte_sent=0;
 
    for (i=0; i<1 ; i++){
        for (k=0; k<20; k++){
            for (j=0; j<32; j++){
                //pc.printf("%3i ",(uint8_t) *(FRAME_BUFFER+i*640+k*32+j));
                sprintf(commandbuffer, "%3i ",(uint8_t) *(FRAME_BUFFER+i*640+k*32+j));
                byte_sent=cs.send(commandbuffer, strlen(commandbuffer));
            }
            //pc.printf("\b\r\n");
            sprintf(commandbuffer, "\b\r\n");
            byte_sent=cs.send(commandbuffer, strlen(commandbuffer));
            
        }
    }   
}

/**
@brief sent via the data socket the frame stored in frame buffer
@param none
@return  the number of byte sent on the socket
*/
int send_frame_ethernet_nohandshake_while(){
   
    int  byte_chunk_sent=0;
    int a=0;
    int pixel_per_chunk=2048;
    int bytes_per_pixel=2;
    int bytes_per_chunk=pixel_per_chunk*bytes_per_pixel;
    int byte_to_send=0;
    int byte_per_image=imSize;
    

    while (byte_chunk_sent<byte_per_image){
        byte_to_send=min(byte_per_image - byte_chunk_sent, bytes_per_chunk);
        
        //pointer are world align. hence the divided by 4
        a = socket.send(FRAME_BUFFER+byte_chunk_sent/4 , byte_to_send);
        if(a<0){
            // non blocking may time out
            //pc.printf("error byte -1/ %d / %d\r\n",a,byte_chunk_sent);
            //return -1;   
        } else {
            byte_chunk_sent += a;
            //pc.printf("%d sent - total sent %d\r\n",a,byte_chunk_sent);
        }
    }
    
    //pc.printf("total of %d bytes sent\r\n",byte_chunk_sent);
    
    return byte_chunk_sent;
        
}



/**********************************************************************************************
*
*       capture function
*
************************************************************************************************/




//https://github.com/tomvdb/stm32f401-nucleo-basic-template/blob/master/Drivers/BSP/STM324x9I_EVAL/stm324x9i_eval_camera.c
/**
@brief start dcmi and start frame capture
@param none
@return  void
*/
void start_capture_10b(){
        
        frame_read=0;
        line_read=0;
        
        //memset(FRAME_BUFFER,0,(size_t) frame_bsize_10b);
        //HAL_DCMI_Stop(&hdcmi);
        //pc.printf("starting snapshot 10b\r\n");
        
        // disable crop features
        //HAL_DCMI_DisableCrop(&hdcmi);
        
        //enable DCMI
        ///HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_SNAPSHOT, (uint32_t) FRAME_BUFFER, Im_size);
        HAL_DCMI_Start_DMA (&hdcmi, DCMI_MODE_SNAPSHOT,(uint32_t) FRAME_BUFFER, (uint32_t) imSize);    
            
        //start capture
        TASK_SPI_WRITE(capture_add,1);
        wait_us(1000);             
        TASK_SPI_WRITE(capture_add,0);

}


/**
@brief suspend DCMI
@param none
@return  void
*/
void suspend_capture(void){
    // Suspend the Camera Capture //
    HAL_DCMI_Suspend(&hdcmi);     
}

/**
@brief resume DCMI
@param none
@return  void
*/
void resume_capture(void) {
    // Start the Camera Capture //
    HAL_DCMI_Resume(&hdcmi);
}

/**
@brief stop DCMI
@param none
@return  void
*/
void stop_capture(void) {
  if(HAL_DCMI_Stop(&hdcmi) == HAL_OK){
     pc.printf("Error stopping camera\n\r");
  }
  else{
      pc.printf("Camera stopped\n\r"); 
    }
}



/**
@brief override interrupt DCMI: on frame callback; send frame
@param none
@return  void
*/
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi){
    pc.printf("frame event callback: read %i lines \r\n",line_read);    
    line_read=0;
    send_frame_ethernet_nohandshake_while();
}

/**
@brief override interrupt DCMI: on vsync callback; increment frame count
@param none
@return  void
*/
void HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef *hdcmi){
    frame_read++;      
}

/**
@brief override interrupt DCMI: on hsync callback; inrement line count
@param none
@return  void
*/
void HAL_DCMI_LineEventCallback (DCMI_HandleTypeDef *hdcmi){  
    line_read++;     
}

/**
@brief debug: set frmae buffer as a known pattern
@param none
@return  void
*/
void format_frame(int imSize){

    for (int i=0;i<480;i++){
        for (int j=0;j<1280;j=j+2){
            *(FRAME_BUFFER+i*1280+j)= (char) j;
            *(FRAME_BUFFER+i*1280+j+1)=(char) (j/256);
        }
        pc.printf("%i - %i - %i\n\r",(int) FRAME_BUFFER, i, (int) FRAME_BUFFER+i*1280);
    }
}



/**********************************************************************************************
*
*       main function
*
************************************************************************************************/

int main(void){
    
         
    uint8_t a,b,c,d=0;
    uint8_t mclk;
    uint8_t unlimited=0;
    int res;
    uint8_t SLEEPN_flag=0;
    uint8_t PBP_flag=0;
    uint8_t OEN_flag=0;
    int status=0;
    int byte_sent;
    char host_cmd[64];
    int loopcount=0;
    int button_pushed=0;
    
    //ethernet 
    char rbuffer[MSG_LEN];
    char * pch;
    int rcount;
    int data=0;
    int add=0;
    int readvalue=0;
    int i=0;
    int sizetosent=64;

    
    //***********************
    /* Initialize all configured peripherals - First thing to do  */ 
    //***********************
    MX_GPIO_Init();
    MX_DMA_Init();
    MX_DCMI_Init_10b();
    
    //************************
    // config serial print
    //************************
    pc.baud(115200);//Set baudrate here. 
    pc.printf("*****************\r\n CIS001  \r\n*****************\r\n");
  
    //************************
    // init pointer
    //************************
    //
    //!!!!!! attention : malloc is in num of words and not byte !!!!!!!! idem memset
    //
    //initialize frame buffer for 10b photo (malloc size en byte)
    //FRAME_BUFFER=(char *) malloc( frame_bsize_10b/4*sizeof(char));
    FRAME_BUFFER=(char *) malloc((size_t) frame_bsize_10b/4);
    //memset((void *)FRAME_BUFFER,2,(size_t) frame_bsize_10b/4); 
    memset((void *)FRAME_BUFFER,2,(size_t) frame_bsize_10b/4); 

    
    //initialize commandbuffer pointer
    commandbuffer=(char *) malloc((MSG_LEN+1)*sizeof(char));
    commandbuffertemp=(char *) malloc((MSG_LEN+1)*sizeof(char));
    
    //************************
    // init spi
    //************************  
    // Setup the spi for 16 bit data (2x8), high steady state clock,second edge capture, with a 5MHz clock rate
    /*  mode | POL PHA
        -----+--------
          0  |  0   0
          1  |  0   1
          2  |  1   0
          3  |  1   1*/
    spi.format(16,0);
    spi.frequency(100000);
    
    
    //start generating MCLK
    uint32_t half_periode=4;
    //MCLK.prescaler(1);
    //MCLK.period_ticks(9);
    //MCLK.pulsewidth_ticks(half_periode);
    //mclk=1;
    
    
    //************************
    // reset leds
    //************************
    led1=0;
    led2=0;
    led3=0;
    
    //************************
    //init CIS001
    //************************
    TASK_INIT();
 
    //************************
    // Ethernet & socket stuff
    //************************
    pc.printf("Connecting Ethernet cable....\r\n");
    eth.connect();
    SocketAddress sockaddr;
    const char *mac = eth.get_mac_address();
    const char* ip = eth.get_ip_address();
    pc.printf("MAC Address is %s\r\n", mac ? mac : "No Mac");
    pc.printf("IP address is: %s\r\n", ip ? ip : "No IP");
    pc.printf("*****************\r\n");
    pc.printf("Nucleo CPU SystemCoreClock is %d MHz\r\n", SystemCoreClock/1000000);
    pc.printf("*****************\r\n");
    
    //************************
    //open a new socket for printing information & debug
    //************************
    status=cs.open(&eth);
    if(status != 0){
        pc.printf("error open com interface\r\n");
        cs.close();
        return 1;
    }
    else{
        pc.printf("com interface open\r\n");
    }
    
    status=cs.connect(ServerIP, portnumber_com);
    if(status !=0){
        pc.printf("error open com socket\r\n");
        cs.close();
        return 1;
    }else{
        pc.printf("socket com open\r\n");
    }
    
    // send 10x test2 to the pc 
    //sprintf(commandbuffer,"%64s","test2");
    //pc.printf("[%s]_%d\r\n",commandbuffer,strlen(commandbuffer));
    //byte_sent=0;
    //for(i=0; i<10;i++){
    //    byte_sent+=cs.send(commandbuffer, strlen(commandbuffer));
    //}
    //sprintf(commandbuffer,"%64s","******************\nHello from Nucleo :)\n******************\n");
    //cs.send(commandbuffer, strlen(commandbuffer));
    
    
    
    
    //************************
    //open a new socket for data and command
    //************************
    status=socket.open(&eth);
    if(status != 0){
        //myprint("*error open interface\r\n");
        pc.printf("failed to Open socket\n\r");
        socket.close();
        return 1;
    }else{
        pc.printf("interface open\r\n");
    }
    
    status=socket.connect(ServerIP, portnumber);
    if(status !=0){
        pc.printf("failed to connect to server\n\r");
        socket.close();
        return 1;
    }else{
        pc.printf("socket open\r\n");
    }
    
    
    
    socket.set_blocking(false); // non blocking 
    socket.set_timeout(1);       // Timeout after (10)ms
  


    //************************
    // Infinite loop
    //************************
    pc.printf("main loop\r\n");
    while (1){
        led2= !led2;
        loopcount++;

        //************************
        // blink led every 1024 loop in the main loop
        //************************
        if(loopcount==1024){    // more or less evey second
            led1=!led1;
            loopcount=0;   
        }
        
        
        //************************************************
        // do soemthing when button is pressed
        //************************************************
        if(button_capture==1 && button_pushed==0){
            pc.printf("bc\n\r");
            button_pushed=1;
            
            // do something here
            
        }else if(button_capture==0 && button_pushed==1){
            button_pushed=0;
        }
        

        //************************************************
        // listening for message (non bloacking)
        //************************************************
        rcount = socket.recv(&rbuffer, sizeof rbuffer);
        if(rcount>0){
            //************************************************
            // something was received :)
            //************************************************
            pc.printf("recv %d bytes [%.*s]\r\n", rcount, strstr(rbuffer, "\n") - rbuffer-1, rbuffer);  // printr xx bytes of rbuffer computed by strstr(x)-x

            pch = strtok (rbuffer," ");
            
            if (pch != NULL) {
                //pc.printf("%s\r\n", pch);
                 
                if (strcmp (pch,"write")==0 || strcmp (pch,"WRITE")==0){
                    
                    pch = strtok (NULL, " ");
                    data=atoi(pch);
                    pch = strtok (NULL, " ");
                    add=atoi(pch);
                    TASK_SPI_WRITE(add,data);
                    
                    sprintf(commandbuffertemp, "done writing %d at %d", data, add);
                    sprintf(commandbuffer,"%64s",commandbuffertemp);
                    byte_sent=cs.send(commandbuffer,strlen(commandbuffer));
                    //pc.printf("[%s]_-_%d\n\r",commandbuffer,byte_sent);
                    
                }else if (strcmp (pch,"read")==0 || strcmp (pch,"READ")==0 ){
                    
                    pch = strtok (NULL, " ");
                    add=atoi(pch);
                    readvalue = TASK_SPI_READ(add);
                    
                    sprintf(commandbuffertemp, "%d/%d", readvalue,add);
                    sprintf(commandbuffer,"%64s",commandbuffertemp);
                    byte_sent=socket.send(commandbuffer,strlen(commandbuffer));
                    //pc.printf("[%s]_-_%d\n\r",commandbuffer,byte_sent);
                    
                    sprintf(commandbuffertemp, "done reading %d at %d", readvalue, add);
                    sprintf(commandbuffer,"%64s",commandbuffertemp);
                    byte_sent=cs.send(commandbuffer,strlen(commandbuffer));
                    //pc.printf("[%s]_-_%d\n\r",commandbuffer,byte_sent);
                    
                }else if (strcmp (pch,"capture")==0 ||strcmp (pch,"CAPTURE")==0){
                    pch = strtok (NULL, " ");
                    pc.printf("[%s]\n\r",pch);
                    imSize=atoi(pch);
                    sprintf(commandbuffertemp, "trying to capture image of %d bytes...", imSize);
                    sprintf(commandbuffer,"%64s",commandbuffertemp);
                    //byte_sent=cs.send(commandbuffer,strlen(commandbuffer));
                    
                    start_capture_10b();
                    if(DEBUG==1){
                        format_frame(imSize);
                        byte_sent=send_frame_ethernet_nohandshake_while();
                        sprintf(commandbuffertemp, "sent image of %d bytes/%d bytes", byte_sent,imSize);
                        sprintf(commandbuffer,"%64s",commandbuffertemp);
                        //byte_sent=cs.send(commandbuffer,strlen(commandbuffer));
                        //pc.printf("[%s]_-_%d\n\r",commandbuffer,byte_sent);
                    }                                   
                    
                }else if (strcmp (pch,"reset")==0 ||strcmp (pch,"RESET")==0){
                    TASK_RSTN();  
                                
                    sprintf(commandbuffertemp, "done reseting chip");
                    sprintf(commandbuffer,"%64s",commandbuffertemp);
                    byte_sent=cs.send(commandbuffer,strlen(commandbuffer));
                    //pc.printf("[%s]_-_%d\n\r",commandbuffer,byte_sent);
                    
                }else if (strcmp (pch,"test_spi")==0 ||strcmp (pch,"TEST_SPI")==0){
                    a=TASK_TEST_SPI();  
                                
                    if (a==1){
                        sprintf(commandbuffertemp, "test spi OK");
                    }else{
                        sprintf(commandbuffertemp, "test spi KO");    
                    }
                    sprintf(commandbuffer,"%64s",commandbuffertemp);
                    byte_sent=cs.send(commandbuffer,strlen(commandbuffer));
                    
                }else if (strcmp (pch,"exit")==0 ||strcmp (pch,"EXIT")==0){             
                    sprintf(commandbuffer, "%64s","close com and data sockets");
                    byte_sent=cs.send(commandbuffer,strlen(commandbuffer));
                    //pc.printf("[%s]_-_%d\n\r",commandbuffer,byte_sent);
                    status=socket.close();
                    status=cs.close();
    
                }else{
                    sprintf(commandbuffer, "%64s","command not recoginzed");
                    byte_sent=cs.send(commandbuffer,strlen(commandbuffer));
                    //pc.printf("[%s]_-_%d\n\r",commandbuffer,byte_sent);
                }
            } else{ //tok is null
                    sprintf(commandbuffer,  "%64s","empty tok");
                    byte_sent=cs.send(commandbuffer,strlen(commandbuffer));
                    //pc.printf("[%s]_-_%d\n\r",commandbuffer,byte_sent);    
            }  
            
        }else{  // non blocking timed out and received <0
        
            //sprintf(commandbuffer, "empty token\r\n");
            //myprint(commandbuffer);
            if(pc.readable()){
                pc.scanf("%s", (char *) &host_cmd);
                pch = strtok (rbuffer," ");
                if (strcmp(host_cmd,"port")==0 || strcmp(host_cmd,"PORT")==0)  {
                    sprintf(commandbuffer, "PORT\r\n");
                    myprint(commandbuffer);
                    
                } else if (strcmp (pch,"write")==0 || strcmp (pch,"WRITE")==0){
                    
                    pch = strtok (NULL, " ");
                    data=atoi(pch);
                    pch = strtok (NULL, " ");
                    add=atoi(pch);
                    TASK_SPI_WRITE(add,data);
                    
                    sprintf(commandbuffer, "write %d at %d", data, add);
                    byte_sent=cs.send(commandbuffer,strlen(commandbuffer));
                    pc.printf("[%s]%d\n\r",commandbuffer,byte_sent);
                    
                }
            }
            
            
        }  //end non blocking timed-out
    
    
    
    
    } //end while(1) loop
    
    
} // end main










/***********************************************************************************************
*
*       configuration function
*
************************************************************************************************/


/**
    *@brief Initialize DCMI in 8b mode
    *@param none
    *@return  void
*/
static void MX_DCMI_Init_8b(void)
{

    hdcmi.Instance = DCMI;
    hdcmi.Init.SynchroMode        = DCMI_SYNCHRO_HARDWARE;
    hdcmi.Init.PCKPolarity        = DCMI_PCKPOLARITY_RISING;
    //hdcmi.Init.PCKPolarity        = DCMI_PCKPOLARITY_FALLING;
    //the data is not valid in the parallel interface, when VSYNC or HSYNC is at that level (high or low)
    hdcmi.Init.VSPolarity         = DCMI_VSPOLARITY_LOW;
    hdcmi.Init.HSPolarity         = DCMI_HSPOLARITY_LOW;
    
    hdcmi.Init.CaptureRate        = DCMI_CR_ALL_FRAME;
    hdcmi.Init.ExtendedDataMode   = DCMI_EXTEND_DATA_8B;
    hdcmi.Init.JPEGMode           = DCMI_JPEG_DISABLE;
    hdcmi.Init.ByteSelectMode     = DCMI_BSM_ALL;
    hdcmi.Init.ByteSelectStart    = DCMI_OEBS_ODD;
    hdcmi.Init.LineSelectMode     = DCMI_LSM_ALL;
    hdcmi.Init.LineSelectStart    = DCMI_OELS_ODD;
    
    if (HAL_DCMI_Init(&hdcmi) != HAL_OK)
    {
    Error_Handler();
    }
  
  
    //check status
    /*HAL_DCMI_StateTypeDef status;
    status=HAL_DCMI_GetState(&hdcmi);
    if(status != HAL_OK){
        pc.printf("DCMI_init: %i\n\r",status);
    }*/

}


/**
  * @brief DCMI Initialization Function
  * @param None
  * @retval None
  */
static void MX_DCMI_Init_10b(void)
{
  
  hdcmi.Instance = DCMI;
  hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
  hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_FALLING;
  hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_LOW;
  hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_LOW;
  hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME;
  hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_10B;
  hdcmi.Init.JPEGMode = DCMI_JPEG_DISABLE;
  hdcmi.Init.ByteSelectMode = DCMI_BSM_ALL;
  hdcmi.Init.ByteSelectStart = DCMI_OEBS_ODD;
  hdcmi.Init.LineSelectMode = DCMI_LSM_ALL;
  hdcmi.Init.LineSelectStart = DCMI_OELS_ODD;
  
  if (HAL_DCMI_Init(&hdcmi) != HAL_OK)
  {
    Error_Handler();
  }
  
  
  /* USER CODE BEGIN DCMI_Init 2 */
    //check status
    /*HAL_DCMI_StateTypeDef status;
    status=HAL_DCMI_GetState(&hdcmi);
    if(status != HAL_OK){
        pc.printf("DCMI_init: %i\n\r",status);
    }*/
  /* USER CODE END DCMI_Init 2 */

}





/**
  * @brief Enable DMA controller clock
  * @param None
  * @retval None
  */
static void MX_DMA_Init(void) 
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();

}




/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */

  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{ 
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */