I have some code to transfer a large amount of data over a SPI port running at the system clock/2 so I need my code to be as fast as possible. The code generated for my current method does not seem to be as optimal as it could be. I am using optimization (8, speed) with the 7.07 C51. Here is a simplified version of my code:
//this variable set in buffer data function static unsigned char xdata * data spiDataPtr; void transferData(void) small { //do not want to store changes in //spiDataPtr so use temp pointer unsigned char xdata * tempPtr; unsigned char data i; unsigned char data temp; tempPtr = spiDataPtr; //transfer set block size for(i = 0xff; i != 0; i--) { SPIDATA = *tempPtr; //initiate transfer tempPtr++; //prepare for next send while busy transfering while(!SPITXDONE); //wait for transfer to complete temp = SPIDATA; //read to avoid colission error } }
Ah, thanks for the information Jon. I was indeed doing a little bit more in the function but I did not think it would matter as I was not manipulating any other xdata variables, just resetting and reusing the tempPtr. After moving the extra code out of the function it compiled the way I thought it should have initially. The ASM example is interesing Oleg and I will keep it in mind for future projects, but for mantainability reasons I am trying to avoid ASM in this project. I actually have the C code set up to do the DJNZ during the wait state and with the DPTR being incemented properly now the extra code of the C version still takes just below the SPI transfer time. There will only be 2 clocks lost by not having the XCH command and that is acceptable. I am using a Cygnal chip so the commands take very few clock cycles. The SPI tx done flag is indeed bit addressable.