페이지

글목록

2016년 2월 7일 일요일

[dialog] SPI memory 를 data memory로 이용하기

지난번 DSPS 프로그램에, Data memory 용 spi 읽기/쓰기를 적용해 봤습니다.

저는 SPI Flash 메모리를 주로 쓰는데, 메모리 용량이 2Mb(256KByte) 나 있으므로 남는 공간이 많습니다. 이 메모리는 처음 부팅시에만 쓰므로 어떻게 하면 사용할 방법이 없을까 하고 고민해 보니 EEPROM 처럼 필요한 데이터를 저장하는 용도로 쓸 수 있겠다 싶어서 테스트 해 봤는데, 잘 되는군요.

안그래도 da14580 은 EEPROM이 없어서 필요한 정보를 전원이 꺼지면 유지할 수가 없어서, EEPROM을 새로 달아야하나 했는데, 이걸로 해결이 되는 군요.

w25x20cl_a02 메모리(2Mbit) 의 제일 마지막 sector(0x3f000)를 사용했고,
Flash memory라 데이터를 쓰기 위해서는 Erase를 먼저 하고 써야 써집니다.
최소 Erase동작은 sector 단위(4KByte)로 할 수 있습니다.
그래서 마지막 섹터의 메모리 어드레스(0x3f000~0x3ffff) 를 지운다음 Write 합니다.

동작만 되는지 확인을 하다 보니 코드가 많이 지저분해 졌습니다.

테스트하기 위해 추가한 함수는 다음과 같습니다.
void app_spi_write_test(void)
{
    uint16_t man_dev_id;
    int16_t i;

wr_data[0] = '0';
for(i = 1 ; i < 512 ; i++)
{
wr_data[i] = wr_data[i-1] + 1;
}
    // Enable FLASH and SPI
    spi_flash_peripheral_init();
    // spi_flash_chip_erase();
    // Read SPI Flash Manufacturer/Device ID
    man_dev_id = spi_read_flash_memory_man_and_dev_id();
    
    spi_cs_low();
    
    spi_cs_high();
    
    spi_flash_write_data(wr_data, 0x3f000, 512);
}

void app_spi_erase_test(void)
{
    // Enable FLASH and SPI
    spi_flash_peripheral_init();
spi_flash_block_erase(0x3f000,SECTOR_ERASE);
}

void app_spi_read_test(void)
{
    int16_t btrd;
    int16_t i;
    uint16_t read_size = 256;  // set this variable to the desired read size
    // Enable FLASH and SPI
    spi_flash_peripheral_init();
    btrd = spi_flash_read_data(rd_data, 0x3f000, read_size);
}

static void spi_flash_peripheral_init()
{
    spi_FLASH_CS_Pad.pin = SPI_CS_PIN;
    spi_FLASH_CS_Pad.port = SPI_GPIO_PORT;
    // Enable SPI & SPI FLASH

    spi_init(&spi_FLASH_CS_Pad, SPI_MODE_8BIT, SPI_ROLE_MASTER, SPI_CLK_IDLE_POL_LOW, SPI_PHA_MODE_0, SPI_MINT_DISABLE, SPI_XTAL_DIV_8);

    detected_spi_flash_device_index = spi_flash_auto_detect();

    if(detected_spi_flash_device_index == 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);
    }
}

이전 프로토콜 테스트 하던 코드에 다음을 추가하여,
스마트폰으로 erase,write,read 테스트를 해 봤습니다.
void app_user_callback(void)
{
        //get data and pointer
        //uint8_t size = app_uart_pull(user_tx_write_pointer, TX_CALLBACK_SIZE, &tx_state_ptr);
int size;
char try_test[100];
while(1)
{
size = app_item_count(&user_buffer);
if (size >= RX_USER_CALLBACK_SIZE)
{
app_user_pull(rx_user_read_pointer, 1);
if (rx_user_read_pointer[0] == '[')
{
app_user_pull(rx_user_read_pointer, RX_USER_CALLBACK_SIZE-1);
if (strncmp(rx_user_read_pointer,"cmd",3) == 0)
{
sprintf(try_test,"cmd recieved OK\n\r");
app_ble_push(try_test,17); // UART Tx out
user_BLE_txbuffer(try_test, 17); // BLE Tx out
}
else if (strncmp(rx_user_read_pointer,"rqm",3) == 0)
{
sprintf(try_test,"rqm recieved OK\n\r");
user_BLE_txbuffer(try_test, 17); // BLE Tx out
app_spi_read_test();
user_BLE_txbuffer(rd_data, 20); // BLE Tx out
}
else if (strncmp(rx_user_read_pointer,"wrm",3) == 0)
{
sprintf(try_test,"wrm recieved OK\n\r");
user_BLE_txbuffer(try_test, 17); // BLE Tx out
app_spi_write_test();
}
else if (strncmp(rx_user_read_pointer,"era",3) == 0)
{
sprintf(try_test,"era recieved OK\n\r");
user_BLE_txbuffer(try_test, 17); // BLE Tx out
app_spi_erase_test();
}
else
{
sprintf(try_test,"cmd recieved FAIL\n\r");
app_ble_push(try_test,19);         // UART Tx out
user_BLE_txbuffer(try_test, 19); // BLE Tx out
}
break;
}
}
else
{
break;
}
}
}

테스트 결과,
Write를 하니 메모리에 0123456.... 을 쓰도록 했는데, 쓰고 나서 읽었더니 제대로 써 진것을 확인하였습니다.


프로그램 소스는 다음 링크에 있습니다.


댓글 없음:

댓글 쓰기