BLEDev

SPIの攻略が必要

各種アドレス番地

製造ID

変数
W25X10CL_MANF_DEV_ID 0xEF10
W25X20CL_MANF_DEV_ID 0xEF11

ページサイズ

変数
W25X10CL_SIZE 131072
W25X20CL_SIZE 262144

ページ数

変数
W25X10CL_PAGE 256
W25X20CL_PAGE 256

SPIセクタサイズ

変数
 SPI_SECTOR_SIZE  4096

配線

pin SPI配線
P0_0 CLK
P0_3 CS
P0_5 DO
P0_6 DI

Manufacture IDの取得

アドレス番地 0x9F にアクセスして取得する。

アドレス番地 定数 解説 
0x50000004 CLK_PER_REG Peripheral divider register
0x50001200 SPI_CTRL_REG SPI control register 0

新規作成

common_uart.c, common_uart.h, common_spi.c, common_spi.h, main.c, periph_setup.c, periph_setup.hは新規作成する。

Keil μVision上では、

src\main.c
src\periph_setup.c
include\periph_setup.h
include\common_uart.h
include\common_spi.h
utilities\common_uart.c
utilities\common_spi.c

Windows上では、

src\main.c
src\periph_setup.c
include\periph_setup.h
include\common_uart.h
include\common_spi.h
utilities\common_uart.c
utilities\common_spi.c

src/main.c

#include <stdio.h>
#include <periph_setup.h>
#include <common_uart.h>
#include <common_spi.h>

int main (void)
{
    perif_init();

    // Init LED
    GPIO_ConfigurePin(GPIO_PORT_0, GPIO_PIN_1, OUTPUT, PID_GPIO, false);

    // Init UART
    GPIO_ConfigurePin(UART_GPIO_PORT, UART_TX_PIN, OUTPUT, PID_UART1_TX, false);
    GPIO_ConfigurePin(UART_GPIO_PORT, UART_RX_PIN, INPUT, PID_UART1_RX, false);

    uart_initialization();

    // Init SPI
    spi_initilization();

    // Get deviceID
    uint16_t devid = get_spi_devid();
    printf_string("-----\r\n");
    printf_string("manufactor_id:");
    printf_byte(devid>>8&0xff);
    printf_byte(devid&0xff);
    printf_string("\r\n");

    // Get Jasmec ID
    uint32_t jedec_id = spi_read_flash_jedec_id();
    printf_string("SPI flash JEDEC ID is ");
    printf_byte((jedec_id>>16)&0xFF);
    printf_byte((jedec_id>>8)&0xFF);
    printf_byte((jedec_id)&0xFF);
    printf_string("\r\n");

    // Get Unique ID
    uint64_t unique_id = spi_read_flash_unique_id();
    printf_string("SPI flash Unique ID Number is ");
    printf_byte(((unique_id>>32)>>24)&0xFF);
    printf_byte(((unique_id>>32)>>16)&0xFF);
    printf_byte(((unique_id>>32)>>8)&0xFF);
    printf_byte((unique_id>>32)&0xFF);
    printf_byte((unique_id>>24)&0xFF);
    printf_byte((unique_id>>16)&0xFF);
    printf_byte((unique_id>>8)&0xFF);
    printf_byte((unique_id)&0xFF);
    printf_string("\r\n");

    // Write
    spi_cs_low();
    spi_cs_high();
    spi_flash_chip_erase();

    uint8_t wr_data[3];
    wr_data[0] = 1;
    wr_data[1] = 2;
    wr_data[2] = 3;
    int pos = 0;
    printf_string("\n\r\n\rWrite...");    
    spi_flash_write_data (wr_data, 0, 3);
    printf_string("Wire result. (");
    printf_byte(spi_flash_read_status_reg());
    printf_string(")\n\r");

    int16_t btrd;
    uint8_t rd_data[3];
    btrd = spi_flash_read_data(rd_data,pos,3);

    // Display Results
    for (int i=0 ; i<3 ; i++){
        printf_byte(rd_data[i]);
        printf_string(" ");
    }

    printf_string("\n\r\n\rBytes Read: 0x");
    printf_byte((btrd>>8)&0xFF);
    printf_byte((btrd)&0xFF);
    printf_string("\n\r");

}

src/periph_setup.c

#include <periph_setup.h>
#include <common_uart.h>

void perif_init() {

    // system init
    SetWord16(CLK_AMBA_REG, 0x00);                 // set clocks (hclk and pclk ) 16MHz
    SetWord16(SET_FREEZE_REG,FRZ_WDOG);            // stop watch dog    
    SetBits16(SYS_CTRL_REG,PAD_LATCH_EN,1);        // open pads
    SetBits16(SYS_CTRL_REG,DEBUGGER_ENABLE,1);     // open debugger
    SetBits16(PMU_CTRL_REG, PERIPH_SLEEP,0);       // exit peripheral power down

    // Power up peripherals' power domain
    SetBits16(PMU_CTRL_REG, PERIPH_SLEEP, 0);
    while (!(GetWord16(SYS_STAT_REG) & PER_IS_UP));

}

include/periph_setup.h

#include <datasheet.h>
#include <gpio.h>
#include <common_uart.h>

// UART Setting
#define UART_BAUDRATE     UART_BAUDRATE_115K2       // Baudrate in bits/s: {9K6, 14K4, 19K2, 28K8, 38K4, 57K6, 115K2}
#define UART_DATALENGTH  UART_DATALENGTH_8        // Datalength in bits: {5, 6, 7, 8}
#define UART_PARITY       UART_PARITY_NONE          // Parity: {UART_PARITY_NONE, UART_PARITY_EVEN, UART_PARITY_ODD}
#define UART_STOPBITS     UART_STOPBITS_1           // Stop bits: {UART_STOPBITS_1, UART_STOPBITS_2} 
#define UART_FLOWCONTROL  UART_FLOWCONTROL_DISABLED // Flow control: {UART_FLOWCONTROL_DISABLED, UART_FLOWCONTROL_ENABLED}
// UART Pin
#define UART_GPIO_PORT    GPIO_PORT_0
#define UART_TX_PIN       GPIO_PIN_7
#define UART_RX_PIN       GPIO_PIN_4
#define UART_ENABLED
// SPI Flash options
#define SPI_FLASH_SIZE 131072             // SPI Flash memory size in bytes
#define SPI_FLASH_PAGE 256                // SPI Flash memory page size in bytes
//SPI initialization parameters
#define SPI_WORD_MODE SPI_8BIT_MODE       // Select SPI bit mode
#define SPI_SMN_MODE  SPI_MASTER_MODE     // {SPI_MASTER_MODE, SPI_SLAVE_MODE}
#define SPI_POL_MODE  SPI_CLK_INIT_HIGH   // {SPI_CLK_INIT_LOW, SPI_CLK_INIT_HIGH}
#define SPI_PHA_MODE  SPI_PHASE_1         // {SPI_PHA_MODE_0, SPI_PHA_MODE_1}
#define SPI_MINT_EN   SPI_NO_MINT         // {SPI_MINT_DISABLE, SPI_MINT_ENABLE}
#define SPI_CLK_DIV   SPI_XTAL_DIV_2      // Select SPI clock divider between 8, 4, 2 and 14
// SPI Pin
#define SPI_GPIO_PORT  GPIO_PORT_0 
#define SPI_CLK_PIN    GPIO_PIN_0
#define SPI_CS_PIN     GPIO_PIN_3
#define SPI_DI_PIN     GPIO_PIN_5
#define SPI_DO_PIN     GPIO_PIN_6 

void perif_init(void);

include/common_uart.h

/**
 ****************************************************************************************
 *
 * @file uart.h
 *
 * @brief uart initialization and print functions header file.
 *
 * Copyright (C) 2012. Dialog Semiconductor Ltd, unpublished work. This computer 
 * program includes Confidential, Proprietary Information and is a Trade Secret of 
 * Dialog Semiconductor Ltd.  All use, disclosure, and/or reproduction is prohibited 
 * unless authorized in writing. All Rights Reserved.
 *
 * <[email protected]> and contributors.
 *
 ****************************************************************************************
 */

#include <stdint.h>

#ifndef UART_H_INCLUDED
#define UART_H_INCLUDED

void uart_initialization(void);
void uart_test(void);

char uart_receive_byte(void);
void uart_send_byte(char ch);
void printf_byte(int a);
void printf_string(char * str);
void printf_byte_dec(int a);


/*
 * ENUMERATION DEFINITIONS
 *****************************************************************************************
 */

 /// Baudrates
enum{
  /// Divider for 115200 bits/s
  UART_BAUDRATE_115K2 =  9,
    /// Divider for 57600 bits/s
  UART_BAUDRATE_57K6  = 17,
    /// Divider for 38400 bits/s
  UART_BAUDRATE_38K4  = 26,
    /// Divider for 28800 bits/s
  UART_BAUDRATE_28K8  = 35,
    /// Divider for 19200 bits/s
  UART_BAUDRATE_19K2  = 52,
    /// Divider for 14400 bits/s
  UART_BAUDRATE_14K4  = 69,
    /// Divider for 9600 bits/s
  UART_BAUDRATE_9K6   = 104,        
    /// Divider for 2400 bits/s
  UART_BAUDRATE_2K4   = 417,
};

/// Character format
enum
{
    /// data length 5 bits
    UART_DATALENGTH_5 = 0,
    /// data length 6 bits
    UART_DATALENGTH_6 = 1,
    /// data length 7 bits
    UART_DATALENGTH_7 = 2,
    /// data length 8 bits
    UART_DATALENGTH_8 = 3
};


/// Parity
enum
{
    /// no parity
    UART_PARITY_NONE     = 0,
    /// even parity
    UART_PARITYBIT_EVEN  = 1,
    /// odd parity
    UART_PARITYBIT_ODD   = 3,
};


/// Stop bit
enum
{
    /// stop bit 1
    UART_STOPBITS_1 = 0,
    /* Note: The number of stop bits is 1.5 if a
     * character format with 5 bit is chosen */
    /// stop bit 2
    UART_STOPBITS_2 = 1
};


/// Flow control
enum
{
    /// disabled auto flow control
    UART_FLOWCONTROL_DISABLED,
    /// enabled auto flow control
    UART_FLOWCONTROL_ENABLED,
};

/*
 * FUNCTION DECLARATIONS
 ****************************************************************************************
 */

  /**
 ****************************************************************************************
 * @brief prints a (16-bit) half-word in hex format using printf_byte
 * @param aHalfWord The 16-bit half-word to print
  * 
 ****************************************************************************************
 */
void print_hword(uint16_t aHalfWord);

 /**
 ****************************************************************************************
 * @brief prints a (32-bit) word in hex format using printf_byte
 * @param aWord The 32-bit word to print
  * 
 ****************************************************************************************
 */
void print_word(uint32_t aWord);



#endif

include/common_spi.h


void uart_spi(void);
int get_spi_devid(void);

utilities/common_uart.c

/**
 ****************************************************************************************
 *
 * @file uart.c
 *
 * @brief (Do not use for your designs) - (legacy) uart initialization & print functions
 *        Please, refer to the Peripheral Drivers documentation for the current uart.c driver
 *
 * Copyright (C) 2012. Dialog Semiconductor Ltd, unpublished work. This computer 
 * program includes Confidential, Proprietary Information and is a Trade Secret of 
 * Dialog Semiconductor Ltd.  All use, disclosure, and/or reproduction is prohibited 
 * unless authorized in writing. All Rights Reserved.
 *
 * <[email protected]> and contributors.
 *
 ****************************************************************************************
 */

#include "global_io.h"
#include "gpio.h"
#include <core_cm0.h>
#include "common_uart.h"
#include "periph_setup.h" 

void uart_initialization(void)
{
    SetBits16(CLK_PER_REG, UART1_ENABLE, 1);      // enable  clock for UART 1

    SetWord16(UART_LCR_REG, 0x80); // set bit to access DLH and DLL register
    SetWord16(UART_IER_DLH_REG,(UART_BAUDRATE_115K2&0xFF>>8));//set high byte
    SetWord16(UART_RBR_THR_DLL_REG,UART_BAUDRATE_115K2&0xFF);//set low byte
    SetWord16(UART_LCR_REG,UART_DATALENGTH|UART_PARITY|UART_STOPBITS);
    SetBits16(UART_MCR_REG, UART_SIRE, 0);  // mode 0 for normal , 1 for IRDA
    SetWord16(UART_IIR_FCR_REG,1);  // enable fifo  
    SetBits16(UART_IER_DLH_REG,ERBFI_dlh0,0);  // IER access, disable interrupt for available data
}
void uart_test(void){
        printf_string("\n\r\n\r*************");
        printf_string("\n\r* UART TEST *\n\r");
        printf_string("*************\n\r");
        printf_string("\n\rHello World! == UART printf_string() ==.\n\r");
}
char uart_receive_byte(void){
    #ifndef UART_ENABLED
        return 0;
#else
    do{
    }while((GetWord16(UART_LSR_REG)&0x01)==0);    // wait until serial data is ready 
    return 0xFF&GetWord16(UART_RBR_THR_DLL_REG);    // read from receive data buffer
#endif
}

void uart_send_byte(char ch){
    #ifndef UART_ENABLED
        return ;
#else
    while((GetWord16(UART_LSR_REG)&0x20)==0);    // read status reg to check if THR is empty
    SetWord16(UART_RBR_THR_DLL_REG,(0xFF&ch)); // write to THR register
    return;
    #endif
}

void printf_string(char * str){
    #ifndef UART_ENABLED
        return ;
#else

    while(*str!=0){          // while not reach the last string character
        uart_send_byte(*str); // send next string character
        str++;
    }
    #endif
}

void printf_byte(int a){          // print a Byte in hex format
    #ifndef UART_ENABLED
        return ;
#else

    char b;
    b=((0xF0&a)>>4);
    b+= (b<10)?48:55;
    uart_send_byte(b);
    b=(0xF&a);
    b+= (b<10)?48:55;
    uart_send_byte(b);
        #endif
}


 /* reverse:  reverse string s in place */
 void reverse(char s[])
 {
    int i, j;
    char c;

    for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
 }

/* itoa:  convert n to characters in s */
 void itoa(int n, char s[])
{
    int i, sign;

    if ((sign = n) < 0)  /* record sign */
        n = -n;          /* make n positive */
    i = 0;
    do {       /* generate digits in reverse order */
        s[i++] = n % 10 + '0';   /* get next digit */
    } while ((n /= 10) > 0);     /* delete it */
    if (sign < 0)
        s[i++] = '-';
    s[i] = '\0';
    reverse(s);
}

void printf_byte_dec(int a){          // print a Byte in decimal format
    char temp_buf[4];
#ifndef UART_ENABLED
    return ;
#else
if ( a>255 )
    return;

    itoa( a,     temp_buf );    

    uart_send_byte(temp_buf[0]);
    uart_send_byte(temp_buf[1]);
    uart_send_byte(temp_buf[2]);
#endif
}



 /**
 ****************************************************************************************
 * @brief prints a (16-bit) half-word in hex format using printf_byte
 * @param aHalfWord The 16-bit half-word to print
  * 
 ****************************************************************************************
 */

void print_hword(uint16_t aHalfWord)
{
    printf_byte((aHalfWord >> 8)& 0xFF);
    printf_byte((aHalfWord)& 0xFF);      
}


 /**
 ****************************************************************************************
 * @brief prints a (32-bit) word in hex format using printf_byte
 * @param aHalfWord The 32-bit word to print
  * 
 ****************************************************************************************
 */

void print_word(uint32_t aWord)
{
    printf_byte((aWord >> 24)& 0xFF);
    printf_byte((aWord >> 16)& 0xFF);
    printf_byte((aWord >> 8)& 0xFF);
    printf_byte((aWord)& 0xFF);      
}

utilities/common_spi.c

#include "common_spi.h"
#include <spi_flash.h>
#include "periph_setup.h" 

SPI_Pad_t spi_FLASH_CS_Pad2;
int8_t detected_spi_flash_device_index2;

void spi_initilization(void){

    // Init SPI    
    GPIO_ConfigurePin( SPI_GPIO_PORT, SPI_CS_PIN, OUTPUT, PID_SPI_EN, true );
    GPIO_ConfigurePin( SPI_GPIO_PORT, SPI_CLK_PIN, OUTPUT, PID_SPI_CLK, false );
    GPIO_ConfigurePin( SPI_GPIO_PORT, SPI_DO_PIN, OUTPUT, PID_SPI_DO, false );    
    GPIO_ConfigurePin( SPI_GPIO_PORT, SPI_DI_PIN, INPUT, PID_SPI_DI, false );

    // Enable FLASH and SPI
    spi_FLASH_CS_Pad2.pin = SPI_CS_PIN;
    spi_FLASH_CS_Pad2.port = SPI_GPIO_PORT;

    // Enable SPI & SPI FLASH
    spi_init(&spi_FLASH_CS_Pad2, SPI_MODE_8BIT, SPI_ROLE_MASTER, SPI_CLK_IDLE_POL_LOW, SPI_PHA_MODE_0, SPI_MINT_DISABLE, SPI_XTAL_DIV_8);    spi_flash_release_from_power_down();

    detected_spi_flash_device_index2 = spi_flash_auto_detect();
  if (detected_spi_flash_device_index2 == SPI_FLASH_AUTO_DETECT_NOT_DETECTED)
    {
            // The device was not identified.
            // The default parameters are used (SPI_FLASH_SIZE, SPI_FLASH_PAGE)
            // Alternatively, an error can be asserted here.
        spi_flash_init(SPI_FLASH_SIZE, SPI_FLASH_PAGE);
    }
}


int get_spi_devid(void){
    // spi_flash_chip_erase();
    // Read SPI Flash Manufacturer/Device ID
    uint16_t man_dev_id = 0;
    man_dev_id = spi_read_flash_memory_man_and_dev_id();

    return man_dev_id;
}

参照で取り込み

コピーで取り込み

include path

..\DA14580_581_583_SDK_3.0.10.1\dk_apps\src\plf\refip\src\arch\boot\rvds;..\DA14580_581_583_SDK_3.0.10.1\dk_apps\src\plf\refip\src\arch\compiler\rvds;..\DA14580_581_583_SDK_3.0.10.1\dk_apps\src\plf\refip\src\arch\ll\rvds;..\DA14580_581_583_SDK_3.0.10.1\dk_apps\src\dialog\include;..\DA14580_581_583_SDK_3.0.10.1\dk_apps\src\plf\refip\src\arch;..\DA14580_581_583_SDK_3.0.10.1\dk_apps\src\plf\refip\src\driver\reg;..\DA14580_581_583_SDK_3.0.10.1\dk_apps\src\plf\refip\src\driver\gpio;.\include;..\DA14580_581_583_SDK_3.0.10.1\dk_apps\src\plf\refip\src\driver\timer;..\DA14580_581_583_SDK_3.0.10.1\dk_apps\src\plf\refip\src\arch\main\ble;..\DA14580_581_583_SDK_3.0.10.1\dk_apps\src\ip\ble\ll\src\hcic;..\DA14580_581_583_SDK_3.0.10.1\dk_apps\src\modules\rwip\api;..\DA14580_581_583_SDK_3.0.10.1\dk_apps\src\ip\ble\ll\src\rwble;..\DA14580_581_583_SDK_3.0.10.1\dk_apps\src\plf\refip\src\driver\uart;.\utilities;..\DA14580_581_583_SDK_3.0.10.1\dk_apps\src\plf\refip\src\driver\spi;..\DA14580_581_583_SDK_3.0.10.1\dk_apps\src\plf\refip\src\driver\spi_flash