While (1) Loop Explanation Please.

if (pf_open("conf2.txt") != FR_OK)  errorHalt("pf_open ");
    
      while (1) {
        UINT nr;
        if (pf_read(buffer, sizeof(buffer), &nr) != FR_OK) errorHalt("pf_read");
        if (nr == 0) break;
        Serial.write(buffer, nr);
      }

The above snippet is from an SD Card library.
I understand that it is an infinite loop until nr == 0.
I am trying to understand what will make nr 0.

Is the loop reading the buffer in reverse order i.e. starting at buffer[sizeof(buffer)] and ending at buffer[0]?

It's the only thing that makes sense to me at the moment.

Sorry this should be under Programming. Would appreciate it being moved - Thanks.

You will notice nr is passed into the pf_read function with a & prefix.

This means it value will be altered in that function.

Lookup parameter passing by reference vs passing by value

#if _USE_READ

FRESULT pf_read (
	void* buff,		/* Pointer to the read buffer (NULL:Forward data to the stream)*/
	UINT btr,		/* Number of bytes to read */
	UINT* br		/* Pointer to number of bytes read */
)
{
	DRESULT dr;
	CLUST clst;
	DWORD sect, remain;
	UINT rcnt;
	BYTE cs, *rbuff = (BYTE*)buff;  // whg
	FATFS *fs = FatFs;


	*br = 0;
	if (!fs) return FR_NOT_ENABLED;		/* Check file system */
	if (!(fs->flag & FA_OPENED))		/* Check if opened */
		return FR_NOT_OPENED;

	remain = fs->fsize - fs->fptr;
	if (btr > remain) btr = (UINT)remain;			/* Truncate btr by remaining bytes */

	while (btr)	{									/* Repeat until all data transferred */
		if ((fs->fptr % 512) == 0) {				/* On the sector boundary? */
			cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1));	/* Sector offset in the cluster */
			if (!cs) {								/* On the cluster boundary? */
				if (fs->fptr == 0)					/* On the top of the file? */
					clst = fs->org_clust;
				else
					clst = get_fat(fs->curr_clust);
				if (clst <= 1) ABORT(FR_DISK_ERR);
				fs->curr_clust = clst;				/* Update current cluster */
			}
			sect = clust2sect(fs->curr_clust);		/* Get current sector */
			if (!sect) ABORT(FR_DISK_ERR);
			fs->dsect = sect + cs;
		}
		rcnt = 512 - (UINT)fs->fptr % 512;			/* Get partial sector data from sector buffer */
		if (rcnt > btr) rcnt = btr;
		dr = disk_readp(!buff ? 0 : rbuff, fs->dsect, (UINT)fs->fptr % 512, rcnt);
		if (dr) ABORT(FR_DISK_ERR);
		fs->fptr += rcnt; rbuff += rcnt;			/* Update pointers and counters */
		btr -= rcnt; *br += rcnt;
	}

	return FR_OK;
}
#endif

I get the gist of what u mean.
I had a look at the function, but it is a bit beyond my current level of understanding.

Could you just point out which line of code in the function changes "nr" - Thanks.

Hi,

There's this line:

*br = 0;

and this one:

*br += rcnt;

Inside the function, the 3rd parameter is known as "br", even though when you call it you give it the variable "nr".

Paul

Thanks PaulRB.

Ok I see now br is the 3rd parameter in pf_read() and nr is the 3rd parameter being passed in the function call.