作者:Bird
上一回在【Maker電子學】Flash 記憶體的原理與應用—PART12 中,我們說明了 SPI NOR flash 的寫入、抹除等待機制、在執行的過程要如何偵測狀態以得知它是否做完,同時我們也說明了寫入或抹除可以被暫停的機制以及暫停可能會帶來什麼影響。
這一回我們要繼續說明資料寫入要如何運作。
寫入開關 #
上一回我們說過,SPI NOR flash 在執行任何寫入、抹除的動作之前,需要先下一個叫做 WE(write enable)的指令,開啟 SPI NOR flash 的寫入模式,這個指令只有一個指令碼 0x06,事實上這就是我們前兩回在介紹 SPI 上的指令格式時,所介紹的第一個指令。

(圖片來源:Bird 提供)
Write enable 指令的有效期間只有一個寫入指令,換句話說,如果我們下了 WE,接著再下一個寫入指令,在寫入結束後,WE 也會一併失效;如果還要再執行另一個寫入或抹除指令,就會需要再下一個 WE 指令。
寫入指令 #
寫入指令與抹除指令最大的不同,就是寫入指令除了指定位址之外,還要提供要寫入的資料,而抹除指令只要提供位址就好,依據指令的不同,4K bytes(sector)、32K bytes、64K bytes 或整個晶片的內容,都會被清成 0xff。
W25Q32JV 的寫入指令叫做 page program,顧名思義它一次最大能寫入一個 page,也就是 256 bytes。

(圖片來源:Bird 提供)
寫入指令以 0x02 的指令碼開始,接著是 24-bit 的寫入位址,然後就是一個 byte 一個 byte 的資料,最多可以有 256 bytes。SPI bus 在動作時只是傳遞資料,真正的寫入動作會發生在 CS 訊號變為 high、結束 SPI 指令後。
實際上,W25Q32JV 內部有一個 256 bytes 的 page buffer,當我們下了寫入指令並將資料送進去時,資料是傳到這個 page buffer 裡,而當實際寫入動作進行時,資料才會從這個 buffer 寫到 NOR flash array 裡面。
因此 W25Q32JV 的 page write 指令一次最多能寫入 256 個 bytes,不過並不是任意的 256 bytes,而是要整個 page 寫,才能一次寫 256 bytes。比方說,如果我對 0x002000 這個位址下寫入指令,接著送入 256 個 bytes 的資料,它就會被寫到 0x002000 – 0x0020ff,這很符合直覺。
但如果我們對 0x002010 這個位址下寫入指令,在一般的狀況下,我們最多就只能送入 250 個 bytes,讓它寫到 0x002010 – 0x0020ff 的區域;如果我們送入第 251 個 byte 的資料,它會繞回去被寫到 0x002000;如果我們送入第 252 個 byte 的資料,它會被寫到 0x002001。
換句話說,如果要寫入連續的 256 個 bytes 資料,寫入指令開始的寫入位址最低一個 byte 必須是 0x00,如果寫入指令開始的寫入位址最低一個 byte 不是 0x00,它增加到 0xff 後就會跳回同一個 page 裡的 0x00 繼續寫入(你還是可以對同一個 page 內寫入最多 256 個 bytes,只是定址起來會變得很不直覺就是了)。
寫入時間 #
根據 datasheet,寫入一個 page 所需要的時間從 0.4 ms 到 3 ms 不等。

(圖片來源:Bird 提供)
寫入所需要的時間主要會跟 flash 的使用次數與壽命有關,越接近壽命結尾時,寫入所需要的時間會越長。
由於寫入所需要的時間不是固定的,我們一樣可以藉由持續讀取 SR1 暫存器的第一個 bit,WIP,來得知寫入的狀態。我們在上一回說明過,這時可以下一個 0x05 指令,然後連續送出 SPI clock,W25Q32JV 就會以每 8 個 clock 為一組送出 SR1 暫存器的內容。

(圖片來源:Bird 提供)
SR1 的最低一個 bit 就是 write in progress。當我們下了寫入指令並開始寫之後,這個 bit 就會變成 1,直到寫入完成,它才會變成 0,因此我們就可以藉由連續讀取 SR1 的值來精確得知寫入完成了沒。
寫入暫停 #
跟 erase 指令一樣,寫入指令也可以用 0x75 這個指令來暫停。在寫入動作進行時,除了讀取 SR1 暫存器外,我們可以用 0x75 這個指令來暫停寫入的動作,寫入暫停後,就可以進行其它的操作,通常是讀取其它位址的內容。
在寫入暫停時,狀態暫存器中的 SUS bit 會被設為 1,代表現在是一個寫入暫停的狀態,此時 W25Q32JV 不能再接受任何跟寫入相關的指令(抹除、寫入都算),只能接受讀取相關的指令。
當我們忙完別的工作後,可以下 0x7A 這個指令來恢復(resume)原先被中斷的寫入動作。下了 resume 指令之後,W25Q32JV 就會回到寫入的狀態,狀態暫存器中的 WIP bit 也會變成 1,讓你可以偵測寫入的狀態,直到動作完成為止。
如果寫入暫停時遭遇不預期的斷電,由於 SUS 這個狀態 bit 並不是 non-volatile 的,它斷電後就會被清除,因此當電源再回來時,W25Q32JV 不會記得它曾經是在寫入暫停的狀態,而原來寫一半的資料可能會損壞,需要更高層的軟體做資料的正確性檢驗。
小結 #
這一回我們說明了寫入指令的使用方式,以及寫入時需要注意的事項。下一回我們要介紹 SPI NOR flash 的保護機制:如何設定某些記憶體區域不會被意外寫入或抹除。
(責任編輯:賴佩萱)