Microchip® Advanced Software Framework

unit_tests.c File Reference

Unit tests for SPI driver.

Copyright (c) 2011-2018 Microchip Technology Inc. and its subsidiaries.

#include <stdint.h>
#include <stdbool.h>
#include <board.h>
#include <sysclk.h>
#include <spi.h>
#include <string.h>
#include <unit_test/suite.h>
#include <stdio_serial.h>
#include <conf_test.h>
#include <conf_board.h>

Data Structures

struct  at25_command
 AT25 command struct. More...
 
struct  spi_command
 SPI command to send. More...
 

Macros

#define AT25_BLOCK_ERASE_32K   0x52
 Block erase command code (32K block). More...
 
#define AT25_BLOCK_ERASE_4K   0x20
 Block erase command code (4K block). More...
 
#define AT25_BLOCK_ERASE_64K   0xD8
 Block erase command code (64K block). More...
 
#define AT25_BYTE_PAGE_PROGRAM   0x02
 Byte/page program command code. More...
 
#define AT25_CHIP_ERASE_1   0x60
 Chip erase command code 1. More...
 
#define AT25_CHIP_ERASE_2   0xC7
 Chip erase command code 2. More...
 
#define AT25_DEEP_PDOWN   0xB9
 Deep power-down command code. More...
 
#define AT25_PROTECT_SECTOR   0x36
 Protect sector command code. More...
 
#define AT25_READ_ARRAY   0x0B
 Read array command code. More...
 
#define AT25_READ_ARRAY_LF   0x03
 Read array (low frequency) command code. More...
 
#define AT25_READ_JEDEC_ID   0x9F
 Read manufacturer and device ID command code. More...
 
#define AT25_READ_SECTOR_PROT   0x3C
 Read sector protection registers command code. More...
 
#define AT25_READ_STATUS   0x05
 Read status register command code. More...
 
#define AT25_RES_DEEP_PDOWN   0xAB
 Resume from deep power-down command code. More...
 
#define AT25_SEQUENTIAL_PROGRAM_1   0xAD
 Sequential program mode command code 1. More...
 
#define AT25_SEQUENTIAL_PROGRAM_2   0xAF
 Sequential program mode command code 2. More...
 
#define AT25_STATUS_EPE   (1 << 5)
 Erase/program error bit. More...
 
#define AT25_STATUS_EPE_ERROR   (1 << 5)
 Erase or program error detected. More...
 
#define AT25_STATUS_EPE_SUCCESS   (0 << 5)
 Erase or program operation is successful. More...
 
#define AT25_STATUS_RDYBSY   (1 << 0)
 Device ready/busy status bit. More...
 
#define AT25_STATUS_RDYBSY_BUSY   (1 << 0)
 Device is busy with internal operations. More...
 
#define AT25_STATUS_RDYBSY_READY   (0 << 0)
 Device is ready. More...
 
#define AT25_STATUS_SPRL   (1 << 7)
 Sector protection registers locked bit. More...
 
#define AT25_STATUS_SPRL_LOCKED   (1 << 7)
 Sector protection registers are locked. More...
 
#define AT25_STATUS_SPRL_UNLOCKED   (0 << 7)
 Sector protection registers are unlocked. More...
 
#define AT25_STATUS_SWP   (3 << 2)
 Software protection status bitfield. More...
 
#define AT25_STATUS_SWP_PROTALL   (3 << 2)
 All sectors are software protected. More...
 
#define AT25_STATUS_SWP_PROTNONE   (0 << 2)
 No sector is software protected. More...
 
#define AT25_STATUS_SWP_PROTSOME   (1 << 2)
 Some sectors are software protected. More...
 
#define AT25_STATUS_WEL   (1 << 1)
 Write enable latch status bit. More...
 
#define AT25_STATUS_WEL_DISABLED   (0 << 1)
 Device is not write enabled. More...
 
#define AT25_STATUS_WEL_ENABLED   (1 << 1)
 Device is write enabled. More...
 
#define AT25_STATUS_WPP   (1 << 4)
 Write protect pin status bit. More...
 
#define AT25_STATUS_WPP_ASSERTED   (1 << 4)
 Write protect signal is asserted. More...
 
#define AT25_STATUS_WPP_NOTASSERTED   (0 << 4)
 Write protect signal is not asserted. More...
 
#define AT25_UNPROTECT_SECTOR   0x39
 Unprotect sector command code. More...
 
#define AT25_WRITE_DISABLE   0x04
 Write disable command code. More...
 
#define AT25_WRITE_ENABLE   0x06
 Write enable command code. More...
 
#define AT25_WRITE_STATUS   0x01
 Write status register command code. More...
 
#define ns_to_dlybct(ck, ns)   ((((ns) / 32 * ((ck) / 1000000)) / 1000) + 1)
 Convert ns to SPI DLYBCT. More...
 
#define ns_to_dlybs(ck, ns)   ((((ns) * ((ck) / 1000000)) / 1000) + 1)
 Convert ns to SPI DLYBS. More...
 
#define OFFSET_CSR   0x30
 Register offset for _CSR. More...
 
#define OFFSET_IER   0x14
 Register offset for _IMR. More...
 
#define OFFSET_MR   0x04
 Register offset for _MR. More...
 
#define SPI_CLK_PHASE   0
 Clock phase. More...
 
#define SPI_CLK_POLARITY   1
 Clock polarity. More...
 
#define SPI_DLYBCT   0x10
 Delay between consecutive transfers. More...
 
#define SPI_DLYBS   0x40
 Delay before SPCK. More...
 
#define TEST_CLOCK   10000000
 Test SPI clock. More...
 
#define TEST_DF_DLYBCT   ns_to_dlybct(sysclk_get_cpu_hz(), 5)
 DLYBCT to use for DF. More...
 
#define TEST_DF_DLYBS   ns_to_dlybs(sysclk_get_cpu_hz(), 10)
 DLYBS to use for DF. More...
 
#define TEST_DF_PCS   ((~(1u << CONF_TEST_DF_NPCS)) & 0xF)
 PCS to use for DF test. More...
 
#define TEST_PATTERN   0xA5
 Byte to transfer for test. More...
 
#define TEST_PCS   ((~(1u << CONF_TEST_SPI_NPCS)) & 0xF)
 PCS to use for test. More...
 

Typedefs

typedef struct at25_command at25_cmd_t
 AT25 command struct. More...
 
typedef struct spi_command spi_cmd_t
 SPI command to send. More...
 

Functions

static bool at25_enable_write (void)
 Enable serial flash write. More...
 
static bool at25_erase_block_4k (const uint32_t address)
 Erase 4K block. More...
 
static bool at25_read (const uint32_t address, uint8_t *p_buf, uint32_t size)
 Read from serial flash. More...
 
static bool at25_read_id (uint32_t *p_id)
 Read the ID of serial flash. More...
 
static bool at25_read_status (uint8_t *p_status)
 Read status register of serial flash. More...
 
static bool at25_unprotect_sector (const uint32_t address)
 Unprotect a sector. More...
 
static bool at25_wait (uint8_t *p_status)
 Wait until serial flash is ready. More...
 
static bool at25_write (const uint32_t address, uint8_t *p_buf, uint32_t size)
 Write to serial flash. More...
 
void CONF_TEST_SPI_HANDLER (void)
 Test SPI interrupt handler. More...
 
int main (void)
 Run SPI driver unit test. More...
 
static void run_spi_ctrl_test (const struct test_case *test)
 Test SPI setting. More...
 
static void run_spi_dataflash_test (const struct test_case *test)
 Test SPI dataflash operations. More...
 
static void run_spi_trans_test (const struct test_case *test)
 Test SPI transfer. More...
 
static void run_spi_writeprotect_test (const struct test_case *test)
 Test SPI write protection. More...
 
static bool spi_send_cmd (spi_cmd_t *p_cmd)
 Send command to dataflash. More...
 

Variables

volatile bool g_b_spi_interrupt_rx_ready = false
 RX interrupt occurred. More...
 
volatile bool g_b_spi_interrupt_tx_ready = false
 TX interrupt occurred. More...
 

#define AT25_BLOCK_ERASE_32K   0x52

Block erase command code (32K block).

#define AT25_BLOCK_ERASE_4K   0x20

Block erase command code (4K block).

Referenced by at25_erase_block_4k().

#define AT25_BLOCK_ERASE_64K   0xD8

Block erase command code (64K block).

#define AT25_BYTE_PAGE_PROGRAM   0x02

Byte/page program command code.

Referenced by at25_write().

#define AT25_CHIP_ERASE_1   0x60

Chip erase command code 1.

#define AT25_CHIP_ERASE_2   0xC7

Chip erase command code 2.

#define AT25_DEEP_PDOWN   0xB9

Deep power-down command code.

#define AT25_PROTECT_SECTOR   0x36

Protect sector command code.

#define AT25_READ_ARRAY   0x0B

Read array command code.

Referenced by at25_read().

#define AT25_READ_ARRAY_LF   0x03

Read array (low frequency) command code.

#define AT25_READ_JEDEC_ID   0x9F

Read manufacturer and device ID command code.

Referenced by at25_read_id().

#define AT25_READ_SECTOR_PROT   0x3C

Read sector protection registers command code.

#define AT25_READ_STATUS   0x05

Read status register command code.

Referenced by at25_read_status().

#define AT25_RES_DEEP_PDOWN   0xAB

Resume from deep power-down command code.

#define AT25_SEQUENTIAL_PROGRAM_1   0xAD

Sequential program mode command code 1.

#define AT25_SEQUENTIAL_PROGRAM_2   0xAF

Sequential program mode command code 2.

#define AT25_STATUS_EPE   (1 << 5)

Erase/program error bit.

Referenced by at25_erase_block_4k(), at25_unprotect_sector(), and at25_write().

#define AT25_STATUS_EPE_ERROR   (1 << 5)

Erase or program error detected.

#define AT25_STATUS_EPE_SUCCESS   (0 << 5)

Erase or program operation is successful.

#define AT25_STATUS_RDYBSY   (1 << 0)

Device ready/busy status bit.

Referenced by at25_wait().

#define AT25_STATUS_RDYBSY_BUSY   (1 << 0)

Device is busy with internal operations.

#define AT25_STATUS_RDYBSY_READY   (0 << 0)

Device is ready.

#define AT25_STATUS_SPRL   (1 << 7)

Sector protection registers locked bit.

#define AT25_STATUS_SPRL_LOCKED   (1 << 7)

Sector protection registers are locked.

#define AT25_STATUS_SPRL_UNLOCKED   (0 << 7)

Sector protection registers are unlocked.

#define AT25_STATUS_SWP   (3 << 2)

Software protection status bitfield.

#define AT25_STATUS_SWP_PROTALL   (3 << 2)

All sectors are software protected.

#define AT25_STATUS_SWP_PROTNONE   (0 << 2)

No sector is software protected.

#define AT25_STATUS_SWP_PROTSOME   (1 << 2)

Some sectors are software protected.

#define AT25_STATUS_WEL   (1 << 1)

Write enable latch status bit.

#define AT25_STATUS_WEL_DISABLED   (0 << 1)

Device is not write enabled.

#define AT25_STATUS_WEL_ENABLED   (1 << 1)

Device is write enabled.

#define AT25_STATUS_WPP   (1 << 4)

Write protect pin status bit.

#define AT25_STATUS_WPP_ASSERTED   (1 << 4)

Write protect signal is asserted.

#define AT25_STATUS_WPP_NOTASSERTED   (0 << 4)

Write protect signal is not asserted.

#define AT25_UNPROTECT_SECTOR   0x39

Unprotect sector command code.

Referenced by at25_unprotect_sector().

#define AT25_WRITE_DISABLE   0x04

Write disable command code.

#define AT25_WRITE_ENABLE   0x06

Write enable command code.

Referenced by at25_enable_write().

#define AT25_WRITE_STATUS   0x01

Write status register command code.

#define ns_to_dlybct (   ck,
  ns 
)    ((((ns) / 32 * ((ck) / 1000000)) / 1000) + 1)

Convert ns to SPI DLYBCT.

#define ns_to_dlybs (   ck,
  ns 
)    ((((ns) * ((ck) / 1000000)) / 1000) + 1)

Convert ns to SPI DLYBS.

#define OFFSET_CSR   0x30

Register offset for _CSR.

Referenced by run_spi_writeprotect_test().

#define OFFSET_IER   0x14

Register offset for _IMR.

#define OFFSET_MR   0x04

Register offset for _MR.

Referenced by run_spi_writeprotect_test().

#define SPI_CLK_PHASE   0

Clock phase.

Referenced by run_spi_dataflash_test(), and run_spi_trans_test().

#define SPI_CLK_POLARITY   1

Clock polarity.

Referenced by run_spi_dataflash_test(), and run_spi_trans_test().

#define SPI_DLYBCT   0x10

Delay between consecutive transfers.

Referenced by run_spi_trans_test().

#define SPI_DLYBS   0x40

Delay before SPCK.

Referenced by run_spi_trans_test().

#define TEST_CLOCK   10000000

Test SPI clock.

Referenced by run_spi_dataflash_test(), and run_spi_trans_test().

#define TEST_DF_DLYBCT   ns_to_dlybct(sysclk_get_cpu_hz(), 5)

DLYBCT to use for DF.

Referenced by run_spi_dataflash_test().

#define TEST_DF_DLYBS   ns_to_dlybs(sysclk_get_cpu_hz(), 10)

DLYBS to use for DF.

Referenced by run_spi_dataflash_test().

#define TEST_DF_PCS   ((~(1u << CONF_TEST_DF_NPCS)) & 0xF)

PCS to use for DF test.

Referenced by spi_send_cmd().

#define TEST_PATTERN   0xA5

Byte to transfer for test.

Referenced by run_spi_trans_test().

#define TEST_PCS   ((~(1u << CONF_TEST_SPI_NPCS)) & 0xF)

PCS to use for test.

Referenced by run_spi_trans_test().

typedef struct at25_command at25_cmd_t

AT25 command struct.

typedef struct spi_command spi_cmd_t

SPI command to send.

static bool at25_enable_write ( void  )
static
static bool at25_erase_block_4k ( const uint32_t  address)
static
static bool at25_read ( const uint32_t  address,
uint8_t *  p_buf,
uint32_t  size 
)
static

Read from serial flash.

Parameters
addressSerial flash internal address.
p_bufPointer to data buffer to fill.
sizeData buffer size.
Returns
True if OK.

References at25_command::address_h, at25_command::address_l, at25_command::address_m, AT25_READ_ARRAY, spi_command::data, at25_command::op_code, and spi_send_cmd().

Referenced by run_spi_dataflash_test().

static bool at25_read_id ( uint32_t *  p_id)
static

Read the ID of serial flash.

Parameters
p_idPointer to fill ID result (word of 4 bytes).
Returns
True if OK.

References AT25_READ_JEDEC_ID, spi_command::data, at25_command::op_code, and spi_send_cmd().

Referenced by run_spi_dataflash_test().

static bool at25_read_status ( uint8_t *  p_status)
static

Read status register of serial flash.

Parameters
p_statusPointer to fill status result.
Returns
True if OK.

References AT25_READ_STATUS, spi_command::data, at25_command::op_code, and spi_send_cmd().

Referenced by at25_wait(), and run_spi_dataflash_test().

static bool at25_unprotect_sector ( const uint32_t  address)
static
static bool at25_wait ( uint8_t *  p_status)
static

Wait until serial flash is ready.

Parameters
p_statusOptional pointer to return the latest status.
Returns
True if OK.

References at25_read_status(), and AT25_STATUS_RDYBSY.

Referenced by at25_erase_block_4k(), at25_unprotect_sector(), and at25_write().

static bool at25_write ( const uint32_t  address,
uint8_t *  p_buf,
uint32_t  size 
)
static

Write to serial flash.

Parameters
addressSerial flash internal address.
p_bufPointer to data buffer to send.
sizeData buffer size.
Returns
True if OK.

References at25_command::address_h, at25_command::address_l, at25_command::address_m, AT25_BYTE_PAGE_PROGRAM, at25_enable_write(), AT25_STATUS_EPE, at25_wait(), spi_command::data, at25_command::op_code, and spi_send_cmd().

Referenced by run_spi_dataflash_test().

void CONF_TEST_SPI_HANDLER ( void  )
static void run_spi_ctrl_test ( const struct test_case test)
static

Test SPI setting.

This test tests SPI reset/enable/disable.

Parameters
testCurrent test case.

References CONF_TEST_SPI, SAM4L, spi_enable(), spi_enable_clock(), spi_is_enabled(), spi_reset(), and test_assert_true.

Referenced by main().

static void run_spi_writeprotect_test ( const struct test_case test)
static

Test SPI write protection.

Parameters
testCurrent test case.

References CONF_TEST_SPI, CONF_TEST_SPI_NPCS, OFFSET_CSR, OFFSET_MR, spi_get_writeprotect_status(), spi_set_writeprotect(), and test_assert_true.

Referenced by main().

volatile bool g_b_spi_interrupt_rx_ready = false

RX interrupt occurred.

Referenced by CONF_TEST_SPI_HANDLER(), and run_spi_trans_test().

volatile bool g_b_spi_interrupt_tx_ready = false

TX interrupt occurred.

Referenced by CONF_TEST_SPI_HANDLER(), and run_spi_trans_test().