summaryrefslogtreecommitdiffstats
path: root/c/src/libchip/i2c/spi-memdrv.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/libchip/i2c/spi-memdrv.c')
-rw-r--r--c/src/libchip/i2c/spi-memdrv.c442
1 files changed, 0 insertions, 442 deletions
diff --git a/c/src/libchip/i2c/spi-memdrv.c b/c/src/libchip/i2c/spi-memdrv.c
deleted file mode 100644
index 593029732e..0000000000
--- a/c/src/libchip/i2c/spi-memdrv.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/*===============================================================*\
-| Project: SPI driver for spi memory devices |
-+-----------------------------------------------------------------+
-| Copyright (c) 2008 |
-| Embedded Brains GmbH |
-| Obere Lagerstr. 30 |
-| D-82178 Puchheim |
-| Germany |
-| rtems@embedded-brains.de |
-+-----------------------------------------------------------------+
-| The license and distribution terms for this file may be |
-| found in the file LICENSE in this distribution or at |
-| |
-| http://www.rtems.org/license/LICENSE. |
-| |
-+-----------------------------------------------------------------+
-\*===============================================================*/
-/*
- * FIXME: currently, this driver only supports read/write accesses
- * erase accesses are to be completed
- */
-
-
-#include <rtems.h>
-#include <rtems/libi2c.h>
-
-#include <libchip/spi-memdrv.h>
-#include <rtems/libio.h>
-
-#define SPI_MEM_CMD_WREN 0x06
-#define SPI_MEM_CMD_WRDIS 0x04
-#define SPI_MEM_CMD_RDID 0x9F
-#define SPI_MEM_CMD_RDSR 0x05
-#define SPI_MEM_CMD_WRSR 0x01
-#define SPI_MEM_CMD_READ 0x03
-#define SPI_MEM_CMD_PP 0x02 /* page program */
-#define SPI_MEM_CMD_SE 0xD8 /* sector erase */
-#define SPI_MEM_CMD_BE 0xC7 /* bulk erase */
-#define SPI_MEM_CMD_DP 0xB9 /* deep power down */
-#define SPI_MEM_CMD_RES 0xAB /* release from deep power down */
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static rtems_status_code spi_memdrv_minor2param_ptr
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| translate given minor device number to param pointer |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_device_minor_number minor, /* minor number of device */
- spi_memdrv_param_t **param_ptr /* ptr to param ptr */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| o = ok or error code |
-\*=========================================================================*/
-{
- rtems_status_code rc = RTEMS_SUCCESSFUL;
- spi_memdrv_t *drv_ptr;
-
- if (rc == RTEMS_SUCCESSFUL) {
- rc = -rtems_libi2c_ioctl(minor,
- RTEMS_LIBI2C_IOCTL_GET_DRV_T,
- &drv_ptr);
- }
- if ((rc == RTEMS_SUCCESSFUL) &&
- (drv_ptr->libi2c_drv_entry.size != sizeof(spi_memdrv_t))) {
- rc = RTEMS_INVALID_SIZE;
- }
- if (rc == RTEMS_SUCCESSFUL) {
- *param_ptr = &(drv_ptr->spi_memdrv_param);
- }
- return rc;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static rtems_status_code spi_memdrv_wait_ms
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| wait a certain interval given in ms |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- int ms /* time to wait in milliseconds */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| o = ok or error code |
-\*=========================================================================*/
-{
- rtems_interval ticks_per_second;
-
- ticks_per_second = rtems_clock_get_ticks_per_second();
- (void) rtems_task_wake_after(ticks_per_second * ms / 1000);
- return 0;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-rtems_status_code spi_memdrv_write
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| write a block of data to flash |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_device_major_number major, /* major device number */
- rtems_device_minor_number minor, /* minor device number */
- void *arg /* ptr to write argument struct */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| o = ok or error code |
-\*=========================================================================*/
-{
- rtems_status_code rc = RTEMS_SUCCESSFUL;
- rtems_libio_rw_args_t *rwargs = arg;
- off_t off = rwargs->offset;
- int cnt = rwargs->count;
- unsigned char *buf = (unsigned char *)rwargs->buffer;
- int bytes_sent = 0;
- int curr_cnt;
- unsigned char cmdbuf[4];
- int ret_cnt = 0;
- int cmd_size;
- spi_memdrv_param_t *mem_param_ptr;
- rtems_libi2c_tfr_mode_t tfr_mode = {
- .baudrate = 20000000, /* maximum bits per second */
- .bits_per_char = 8, /* how many bits per byte/word/longword? */
- .lsb_first = FALSE, /* FALSE: send MSB first */
- .clock_inv = FALSE, /* FALSE: non-inverted clock (high active) */
- .clock_phs = FALSE /* FALSE: clock starts in middle of data tfr */
- } ;
-
- /*
- * get mem parameters
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = spi_memdrv_minor2param_ptr(minor,&mem_param_ptr);
- }
- /*
- * check arguments
- */
- if (rc == RTEMS_SUCCESSFUL) {
- if ((cnt <= 0) ||
- (cnt > mem_param_ptr->mem_size) ||
- (off > (mem_param_ptr->mem_size-cnt))) {
- rc = RTEMS_INVALID_SIZE;
- }
- else if (buf == NULL) {
- rc = RTEMS_INVALID_ADDRESS;
- }
- }
- while ((rc == RTEMS_SUCCESSFUL) &&
- (cnt > bytes_sent)) {
- curr_cnt = cnt - bytes_sent;
- if ((mem_param_ptr->page_size > 0) &&
- (off / mem_param_ptr->page_size) !=
- ((off+curr_cnt+1) / mem_param_ptr->page_size)) {
- curr_cnt = mem_param_ptr->page_size - (off % mem_param_ptr->page_size);
- }
- /*
- * select device, set transfer mode, address device
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_start(minor);
- }
- /*
- * set transfer mode
- */
- if (rc == RTEMS_SUCCESSFUL) {
- tfr_mode.baudrate = mem_param_ptr->baudrate;
- rc = -rtems_libi2c_ioctl(minor,
- RTEMS_LIBI2C_IOCTL_SET_TFRMODE,
- &tfr_mode);
- }
-
- /*
- * address device
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_addr(minor,TRUE);
- }
-
- /*
- * send write_enable command
- */
- if (rc == RTEMS_SUCCESSFUL) {
- cmdbuf[0] = SPI_MEM_CMD_WREN;
- ret_cnt = rtems_libi2c_write_bytes(minor,cmdbuf,1);
- if (ret_cnt < 0) {
- rc = -ret_cnt;
- }
- }
- /*
- * terminate transfer
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_stop(minor);
- }
- /*
- * select device, set transfer mode
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_start(minor);
- }
-
- /*
- * address device
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_addr(minor,TRUE);
- }
-
- /*
- * set transfer mode
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = -rtems_libi2c_ioctl(minor,
- RTEMS_LIBI2C_IOCTL_SET_TFRMODE,
- &tfr_mode);
- }
- /*
- * send "page program" command and address
- */
- if (rc == RTEMS_SUCCESSFUL) {
- cmdbuf[0] = SPI_MEM_CMD_PP;
- if (mem_param_ptr->mem_size > 0x10000 /* 256*256 */) {
- cmdbuf[1] = (off >> 16) & 0xff;
- cmdbuf[2] = (off >> 8) & 0xff;
- cmdbuf[3] = (off >> 0) & 0xff;
- cmd_size = 4;
- }
- else if (mem_param_ptr->mem_size > 256) {
- cmdbuf[1] = (off >> 8) & 0xff;
- cmdbuf[2] = (off >> 0) & 0xff;
- cmd_size = 3;
- }
- else {
- cmdbuf[1] = (off >> 0) & 0xff;
- cmd_size = 1;
- }
-
- ret_cnt = rtems_libi2c_write_bytes(minor,cmdbuf,cmd_size);
- if (ret_cnt < 0) {
- rc = -ret_cnt;
- }
- }
- /*
- * send write data
- */
- if (rc == RTEMS_SUCCESSFUL) {
- ret_cnt = rtems_libi2c_write_bytes(minor,buf,curr_cnt);
- if (ret_cnt < 0) {
- rc = -ret_cnt;
- }
- }
- /*
- * terminate transfer
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_stop(minor);
- }
- /*
- * wait proper time for data to store: 5ms
- * FIXME: select proper interval or poll, until device is finished
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = spi_memdrv_wait_ms(5);
- }
- /*
- * adjust bytecount to be sent and pointers
- */
- bytes_sent += curr_cnt;
- off += curr_cnt;
- buf += curr_cnt;
- }
- rwargs->bytes_moved = bytes_sent;
- return rc;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-rtems_status_code spi_memdrv_read
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| read a block of data from flash |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_device_major_number major, /* major device number */
- rtems_device_minor_number minor, /* minor device number */
- void *arg /* ptr to read argument struct */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| o = ok or error code |
-\*=========================================================================*/
-{
- rtems_status_code rc = RTEMS_SUCCESSFUL;
- rtems_libio_rw_args_t *rwargs = arg;
- off_t off = rwargs->offset;
- int cnt = rwargs->count;
- unsigned char *buf = (unsigned char *)rwargs->buffer;
- unsigned char cmdbuf[4];
- int ret_cnt = 0;
- int cmd_size;
- spi_memdrv_param_t *mem_param_ptr;
- rtems_libi2c_tfr_mode_t tfr_mode = {
- .baudrate = 20000000, /* maximum bits per second */
- .bits_per_char = 8, /* how many bits per byte/word/longword? */
- .lsb_first = FALSE, /* FALSE: send MSB first */
- .clock_inv = FALSE, /* FALSE: non-inverted clock (high active) */
- .clock_phs = FALSE /* FALSE: clock starts in middle of data tfr */
- };
-
- /*
- * get mem parameters
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = spi_memdrv_minor2param_ptr(minor,&mem_param_ptr);
- }
- /*
- * check arguments
- */
- if (rc == RTEMS_SUCCESSFUL) {
- if ((cnt <= 0) ||
- (cnt > mem_param_ptr->mem_size) ||
- (off > (mem_param_ptr->mem_size-cnt))) {
- rc = RTEMS_INVALID_SIZE;
- }
- else if (buf == NULL) {
- rc = RTEMS_INVALID_ADDRESS;
- }
- }
- /*
- * select device, set transfer mode, address device
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_start(minor);
- }
- /*
- * set transfer mode
- */
- if (rc == RTEMS_SUCCESSFUL) {
- tfr_mode.baudrate = mem_param_ptr->baudrate;
- rc = -rtems_libi2c_ioctl(minor,
- RTEMS_LIBI2C_IOCTL_SET_TFRMODE,
- &tfr_mode);
- }
- /*
- * address device
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_addr(minor,TRUE);
- }
-
- if (off >= mem_param_ptr->mem_size) {
- /*
- * HACK: beyond size of memory array? then read status register instead
- */
- /*
- * send read status register command
- */
- if (rc == RTEMS_SUCCESSFUL) {
- cmdbuf[0] = SPI_MEM_CMD_RDSR;
- ret_cnt = rtems_libi2c_write_bytes(minor,cmdbuf,1);
- if (ret_cnt < 0) {
- rc = -ret_cnt;
- }
- }
- }
- else {
- /*
- * send read command and address
- */
- if (rc == RTEMS_SUCCESSFUL) {
- cmdbuf[0] = SPI_MEM_CMD_READ;
- if (mem_param_ptr->mem_size > 0x10000 /* 256*256 */) {
- cmdbuf[1] = (off >> 16) & 0xff;
- cmdbuf[2] = (off >> 8) & 0xff;
- cmdbuf[3] = (off >> 0) & 0xff;
- cmd_size = 4;
- }
- else if (mem_param_ptr->mem_size > 256) {
- cmdbuf[1] = (off >> 8) & 0xff;
- cmdbuf[2] = (off >> 0) & 0xff;
- cmd_size = 3;
- }
- else {
- cmdbuf[1] = (off >> 0) & 0xff;
- cmd_size = 1;
- }
- ret_cnt = rtems_libi2c_write_bytes(minor,cmdbuf,cmd_size);
- if (ret_cnt < 0) {
- rc = -ret_cnt;
- }
- }
- }
- /*
- * fetch read data
- */
- if (rc == RTEMS_SUCCESSFUL) {
- ret_cnt = rtems_libi2c_read_bytes (minor,buf,cnt);
- if (ret_cnt < 0) {
- rc = -ret_cnt;
- }
- }
-
- /*
- * terminate transfer
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_stop(minor);
- }
- rwargs->bytes_moved = (rc == RTEMS_SUCCESSFUL) ? ret_cnt : 0;
-
- return rc;
-}
-
-/*
- * driver operation tables
- */
-rtems_driver_address_table spi_memdrv_rw_ops = {
- .read_entry = spi_memdrv_read,
- .write_entry = spi_memdrv_write
-};
-
-rtems_driver_address_table spi_memdrv_ro_ops = {
- .read_entry = spi_memdrv_read,
-};
-