Skip to content

Commit 4863564

Browse files
ajucklerxiaoxiang781216
authored andcommitted
drivers/eeprom: Support PE/SE/CE commands
Add support for the page erase (PE), sector erase (SE) and chip erase (CE) dedicated commands on supported devices. They can be triggered using the corresponding IOCTL commands EEPIOC_PAGEERASE, EEPIOC_SECTORERASE and EEPIOC_CHIPERASE. On unsupported devices, this is equivalent to writing a full page, sector, or the entire EEPROM to 0xFF. Signed-off-by: Antoine Juckler <6445757+ajuckler@users.noreply.github.com>
1 parent bf391cc commit 4863564

File tree

4 files changed

+458
-5
lines changed

4 files changed

+458
-5
lines changed

Documentation/components/drivers/character/eeprom.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,25 @@ The full list of ``ioctl()`` commands can be found in
165165

166166
Set the SPI/I2C bus frequency
167167

168+
- ``EEPIOC_PAGEERASE``
169+
*Argument:* ``unsigned long``
170+
171+
Erase an EEPROM page given its index, a dedicated command is used if
172+
supported by the device.
173+
174+
- ``EEPIOC_SECTORERASE``
175+
*Argument:* ``unsigned long``
176+
177+
Erase an EEPROM sector given its index, a dedicated command is used if
178+
supported by the device. Equivalent to a page erase on devices without
179+
sectors.
180+
181+
- ``EEPIOC_CHIPERASE``
182+
*Argument:* ``void``
183+
184+
Erase the full EEPROM, a dedicated command is used if supported by the
185+
device.
186+
168187
File Systems
169188
============
170189

drivers/eeprom/i2c_xx24xx.c

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,147 @@ static int ee24xx_writepage(FAR struct ee24xx_dev_s *eedev, uint32_t memaddr,
327327
return I2C_TRANSFER(eedev->i2c, msgs, 2);
328328
}
329329

330+
/****************************************************************************
331+
* Name: ee24xx_eraseall
332+
*
333+
* Description:
334+
* Erase all data on the device
335+
*
336+
* Input Parameters:
337+
* eedev - Device structure
338+
*
339+
****************************************************************************/
340+
341+
static int ee24xx_eraseall(FAR struct ee24xx_dev_s *eedev)
342+
{
343+
FAR char *buf;
344+
off_t offset;
345+
int ret;
346+
347+
DEBUGASSERT(eedev);
348+
349+
if (eedev->readonly)
350+
{
351+
return -EACCES;
352+
}
353+
354+
buf = kmm_malloc(eedev->pgsize);
355+
if (buf == NULL)
356+
{
357+
ferr("ERROR: Failed to allocate memory for ee24xx eraseall\n");
358+
return -ENOMEM;
359+
}
360+
361+
memset(buf, 0xff, eedev->pgsize);
362+
363+
ret = nxmutex_lock(&eedev->lock);
364+
if (ret < 0)
365+
{
366+
goto free_buffer;
367+
}
368+
369+
for (offset = 0; offset < eedev->size; offset += eedev->pgsize)
370+
{
371+
ret = ee24xx_writepage(eedev, offset, buf, eedev->pgsize);
372+
if (ret < 0)
373+
{
374+
ferr("ERROR: Failed to write page at offset %" PRIdOFF
375+
" (ret = %d)",
376+
offset, ret);
377+
goto release_semaphore;
378+
}
379+
380+
ret = ee24xx_waitwritecomplete(eedev, offset);
381+
if (ret < 0)
382+
{
383+
ferr("ERROR while waiting for write at offset %" PRIdOFF
384+
" to complete (ret = %d)",
385+
offset, ret);
386+
goto release_semaphore;
387+
}
388+
}
389+
390+
release_semaphore:
391+
nxmutex_unlock(&eedev->lock);
392+
393+
free_buffer:
394+
kmm_free(buf);
395+
return ret;
396+
}
397+
398+
/****************************************************************************
399+
* Name: ee24xx_erasepage
400+
*
401+
* Description:
402+
* Erase 1 page of data
403+
*
404+
* Input Parameters:
405+
* eedev - Device structure
406+
* index - Index of the page to erase
407+
*
408+
* Returned Value:
409+
* Zero (OK) on success; a negated errno value on failure.
410+
*
411+
****************************************************************************/
412+
413+
static int ee24xx_erasepage(FAR struct ee24xx_dev_s *eedev,
414+
unsigned long index)
415+
{
416+
FAR char *buf;
417+
int ret;
418+
off_t offset;
419+
420+
DEBUGASSERT(eedev);
421+
DEBUGASSERT(eedev->pgsize > 0);
422+
423+
if (eedev->readonly)
424+
{
425+
return -EACCES;
426+
}
427+
428+
if (index >= (eedev->size / eedev->pgsize))
429+
{
430+
return -EFBIG;
431+
}
432+
433+
buf = kmm_malloc(eedev->pgsize);
434+
435+
if (buf == NULL)
436+
{
437+
ferr("ERROR: Failed to allocate memory for ee24xx_erasepage\n");
438+
return -ENOMEM;
439+
}
440+
441+
memset(buf, 0xff, eedev->pgsize);
442+
443+
ret = nxmutex_lock(&eedev->lock);
444+
if (ret < 0)
445+
{
446+
goto free_buffer;
447+
}
448+
449+
offset = index * eedev->pgsize;
450+
ret = ee24xx_writepage(eedev, offset, buf, eedev->pgsize);
451+
if (ret < 0)
452+
{
453+
ferr("ERROR: Failed to write page (ret = %d)", ret);
454+
goto release_semaphore;
455+
}
456+
457+
ret = ee24xx_waitwritecomplete(eedev, offset);
458+
if (ret < 0)
459+
{
460+
ferr("ERROR while waiting for write to complete (ret = %d)", ret);
461+
}
462+
463+
release_semaphore:
464+
nxmutex_unlock(&eedev->lock);
465+
466+
free_buffer:
467+
kmm_free(buf);
468+
return ret;
469+
}
470+
330471
/****************************************************************************
331472
* Driver Functions
332473
****************************************************************************/
@@ -814,6 +955,15 @@ static int ee24xx_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
814955
}
815956
break;
816957

958+
case EEPIOC_PAGEERASE:
959+
case EEPIOC_SECTORERASE:
960+
ret = ee24xx_erasepage(eedev, arg);
961+
break;
962+
963+
case EEPIOC_CHIPERASE:
964+
ret = ee24xx_eraseall(eedev);
965+
break;
966+
817967
default:
818968
ret = -ENOTTY;
819969
}

0 commit comments

Comments
 (0)