diff options
author | Evan Lojewski <github@meklort.com> | 2020-01-22 19:21:24 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-22 19:21:24 -0700 |
commit | d0e143ed6a338dc33241563d8784de8075ab8e3f (patch) | |
tree | 1e01ebdd7e7eb7d581c4491fe79acb61cdf66d5e /libs | |
parent | 8a729f6e1d5feb07e8e5d4003895dbf484a99767 (diff) | |
download | bcm5719-ortega-d0e143ed6a338dc33241563d8784de8075ab8e3f.tar.gz bcm5719-ortega-d0e143ed6a338dc33241563d8784de8075ab8e3f.zip |
NVM: Refactor EM100 code to add a generic NVM bitbang api. (#17)
Diffstat (limited to 'libs')
-rw-r--r-- | libs/NVRam/CMakeLists.txt | 3 | ||||
-rw-r--r-- | libs/NVRam/EM100.c | 85 | ||||
-rw-r--r-- | libs/NVRam/bitbang.c | 218 | ||||
-rw-r--r-- | libs/NVRam/include/NVRam.h | 10 |
4 files changed, 239 insertions, 77 deletions
diff --git a/libs/NVRam/CMakeLists.txt b/libs/NVRam/CMakeLists.txt index adf74a5..becf0e8 100644 --- a/libs/NVRam/CMakeLists.txt +++ b/libs/NVRam/CMakeLists.txt @@ -10,7 +10,7 @@ ### ################################################################################ ### -### @copyright Copyright (c) 2018, Evan Lojewski +### @copyright Copyright (c) 2018-2020, Evan Lojewski ### @cond ### ### All rights reserved. @@ -46,6 +46,7 @@ project(NVRam) SET(SOURCES nvm.c + bitbang.c EM100.c crc.c include/NVRam.h diff --git a/libs/NVRam/EM100.c b/libs/NVRam/EM100.c index c8382b3..3aa3c93 100644 --- a/libs/NVRam/EM100.c +++ b/libs/NVRam/EM100.c @@ -10,7 +10,7 @@ /// //////////////////////////////////////////////////////////////////////////////// /// -/// @copyright Copyright (c) 2019, Evan Lojewski +/// @copyright Copyright (c) 2019-2020, Evan Lojewski /// @cond /// /// All rights reserved. @@ -79,74 +79,6 @@ uint8_t gEM100Packet[64] = { #define EM100_PACKET_BUFFER_OFFSET (9u) #define EM100_MAX_BUFFER_LEN (sizeof(gEM100Packet) - EM100_PACKET_BUFFER_OFFSET) -void NVRAM_EM100_send_byte(uint8_t byte) -{ - RegNVMWrite_t nvm_write; - nvm_write.r32 = 0; - - for (int i = 7; i >= 0; i--) - { - // Setup the SI value - nvm_write.bits.SCLKOutputValue = 0; - nvm_write.bits.SIOutputValue = (byte & (1 << i)) ? 1 : 0; - NVM.Write.r32 = nvm_write.r32; - - // Clock data out. - nvm_write.bits.SCLKOutputValue = 1; - NVM.Write.r32 = nvm_write.r32; - } - - // Final clock edge - nvm_write.bits.SCLKOutputValue = 0; - nvm_write.bits.SIOutputValue = 0; - NVM.Write.r32 = nvm_write.r32; -} - -bool NVRam_EM100_writeBytes(uint8_t bytes[], size_t num_bytes) -{ - // Aquire the lock - if(!NVRam_acquireLock()) - { - // Unable to lock. - return false; - } - NVRam_enable(); - - // Save defaults and set sane values - RegNVMNvmCfg1_t cfg1_orig; - RegNVMNvmCfg1_t cfg1_bitbang; - cfg1_orig.r32 = NVM.NvmCfg1.r32; - cfg1_bitbang.r32 = cfg1_orig.r32; - cfg1_bitbang.bits.BitbangMode = 1; - - // Drive the SCLK, CSb and MOSI lines - RegNVMAddr_t nvm_od; - nvm_od.r32 = 0xffffff; // All Input - nvm_od.bits.SCLKOutputDisable = 0; // Drive SCLK - nvm_od.bits.CSbOutputDisable = 0; // Drive CSb - nvm_od.bits.SIOutputDisable = 0; // Drive MOSI - - RegNVMWrite_t nvm_write; - - NVM.Addr.r32 = nvm_od.r32; - NVM.Write.r32 = nvm_write.r32; - // Enable Bitbang mode - NVM.NvmCfg1.r32 = cfg1_bitbang.r32; - - for (int i = 0; i < num_bytes; i++) - { - NVRAM_EM100_send_byte(bytes[i]); - } - - // Restore Cfg1. - NVM.NvmCfg1.r32 = cfg1_orig.r32; - - NVRam_disable(); - NVRam_releaseLock(); - - return true; -} - void NVRam_EM100_putchar(char c) { int used_buffer = gEM100Packet[EM100_PACKET_MSG_LEN] + 1; @@ -160,17 +92,18 @@ void NVRam_EM100_putchar(char c) #if ENABLE_CONSOLE NVRam_EM100_enableConsole(); #endif - if(NVRam_EM100_writeBytes(gEM100Packet, EM100_PACKET_BUFFER_OFFSET + used_buffer)) + if (NVRam_sendBytes(gEM100Packet, EM100_PACKET_BUFFER_OFFSET + used_buffer)) { // Mark buffer as empty gEM100Packet[EM100_PACKET_MSG_LEN] = 0; } else { - if(used_buffer >= EM100_MAX_BUFFER_LEN) + if (used_buffer >= EM100_MAX_BUFFER_LEN) { // Don't output any more chars - gEM100Packet[EM100_PACKET_MSG_LEN] = used_buffer - 1;; + gEM100Packet[EM100_PACKET_MSG_LEN] = used_buffer - 1; + ; } } #if ENABLE_CONSOLE @@ -185,9 +118,9 @@ void NVRam_EM100_enableConsole(void) uint8_t packet_AA[] = { EM100_CONSOLE_WRITE_COMMAND, 0x00, 0xAA, 0xAA, 0x00 }; uint8_t packet_55[] = { EM100_CONSOLE_WRITE_COMMAND, 0x00, 0x55, 0x55, 0x00 }; - NVRam_EM100_writeBytes(packet_AA, sizeof(packet_AA)); - NVRam_EM100_writeBytes(packet_55, sizeof(packet_AA)); - NVRam_EM100_writeBytes(packet_AA, sizeof(packet_AA)); + NVRam_sendBytes(packet_AA, sizeof(packet_AA)); + NVRam_sendBytes(packet_55, sizeof(packet_AA)); + NVRam_sendBytes(packet_AA, sizeof(packet_AA)); } void NVRam_EM100_disableConsole(void) @@ -198,6 +131,6 @@ void NVRam_EM100_disableConsole(void) EM100_CMD_EXIT_CONSOLE, 0x00, }; - NVRam_EM100_writeBytes(packet_exit_console, sizeof(packet_exit_console)); + NVRam_sendBytes(packet_exit_console, sizeof(packet_exit_console)); } #endif /* ENABLE_CONSOLE */
\ No newline at end of file diff --git a/libs/NVRam/bitbang.c b/libs/NVRam/bitbang.c new file mode 100644 index 0000000..5d01d9d --- /dev/null +++ b/libs/NVRam/bitbang.c @@ -0,0 +1,218 @@ +//////////////////////////////////////////////////////////////////////////////// +/// +/// @file bitbang.c +/// +/// @project +/// +/// @brief NVRam bitbang Routines +/// +//////////////////////////////////////////////////////////////////////////////// +/// +//////////////////////////////////////////////////////////////////////////////// +/// +/// @copyright Copyright (c) 2019-2020, Evan Lojewski +/// @cond +/// +/// All rights reserved. +/// +/// Redistribution and use in source and binary forms, with or without +/// modification, are permitted provided that the following conditions are met: +/// 1. Redistributions of source code must retain the above copyright notice, +/// this list of conditions and the following disclaimer. +/// 2. Redistributions in binary form must reproduce the above copyright notice, +/// this list of conditions and the following disclaimer in the documentation +/// and/or other materials provided with the distribution. +/// 3. Neither the name of the copyright holder nor the +/// names of its contributors may be used to endorse or promote products +/// derived from this software without specific prior written permission. +/// +//////////////////////////////////////////////////////////////////////////////// +/// +/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +/// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +/// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +/// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +/// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +/// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +/// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +/// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +/// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +/// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +/// POSSIBILITY OF SUCH DAMAGE. +/// @endcond +//////////////////////////////////////////////////////////////////////////////// +#include "bcm5719_NVM.h" + +#include <NVRam.h> + +void NVRAM_sendByte(uint8_t byte) +{ + RegNVMWrite_t nvm_write; + nvm_write.r32 = 0; + + for (int i = 7; i >= 0; i--) + { + // Setup the SI value + nvm_write.bits.SCLKOutputValue = 0; + nvm_write.bits.SIOutputValue = (byte & (1 << i)) ? 1 : 0; + NVM.Write.r32 = nvm_write.r32; + + // Clock data out. + nvm_write.bits.SCLKOutputValue = 1; + NVM.Write.r32 = nvm_write.r32; + } + + // Final clock edge + nvm_write.bits.SCLKOutputValue = 0; + nvm_write.bits.SIOutputValue = 0; + NVM.Write.r32 = nvm_write.r32; +} + +uint8_t NVRAM_sendAndGetByte(uint8_t byte) +{ + uint8_t readByte = 0; + RegNVMWrite_t nvm_write; + nvm_write.r32 = 0; + + for (int i = 7; i >= 0; i--) + { + // Setup the SI value + nvm_write.bits.SCLKOutputValue = 0; + nvm_write.bits.SIOutputValue = (byte & (1 << i)) ? 1 : 0; + NVM.Write.r32 = nvm_write.r32; + + // Clock data out. + nvm_write.bits.SCLKOutputValue = 1; + NVM.Write.r32 = nvm_write.r32; + + // Read Input value. + readByte |= NVM.Read.bits.SOInputValue ? (1 << i) : 0; + } + + // Final clock edge + nvm_write.bits.SCLKOutputValue = 0; + nvm_write.bits.SIOutputValue = 0; + NVM.Write.r32 = nvm_write.r32; + + return readByte; +} + +bool NVRam_sendBytes(uint8_t bytes[], uint32_t num_bytes) +{ + // Aquire the lock + if (!NVRam_acquireLock()) + { + // Unable to lock. + return false; + } + NVRam_enable(); + + // Save defaults and set sane values + RegNVMNvmCfg1_t cfg1_orig; + RegNVMNvmCfg1_t cfg1_bitbang; + cfg1_orig.r32 = NVM.NvmCfg1.r32; + cfg1_bitbang.r32 = cfg1_orig.r32; + cfg1_bitbang.bits.BitbangMode = 1; + + // Drive the SCLK, CSb and MOSI lines + RegNVMAddr_t nvm_od; + nvm_od.r32 = 0xffffff; // All Input + nvm_od.bits.SCLKOutputDisable = 0; // Drive SCLK + nvm_od.bits.CSbOutputDisable = 0; // Drive CSb + nvm_od.bits.SIOutputDisable = 0; // Drive MOSI + + RegNVMWrite_t nvm_write; + + NVM.Addr.r32 = nvm_od.r32; + NVM.Write.r32 = nvm_write.r32; + // Enable Bitbang mode + NVM.NvmCfg1.r32 = cfg1_bitbang.r32; + + for (int i = 0; i < num_bytes; i++) + { + NVRAM_sendByte(bytes[i]); + } + + // Restore Cfg1. + NVM.NvmCfg1.r32 = cfg1_orig.r32; + + NVRam_disable(); + NVRam_releaseLock(); + + return true; +} + +bool NVRam_sendAndGetBytes(uint8_t send_bytes[], uint8_t get_bytes[], int32_t num_bytes) +{ + // Aquire the lock + if (!NVRam_acquireLock()) + { + // Unable to lock. + return false; + } + NVRam_enable(); + + // Save defaults and set sane values + RegNVMNvmCfg1_t cfg1_orig; + RegNVMNvmCfg1_t cfg1_bitbang; + cfg1_orig.r32 = NVM.NvmCfg1.r32; + cfg1_bitbang.r32 = cfg1_orig.r32; + cfg1_bitbang.bits.BitbangMode = 1; + + // Drive the SCLK, CSb and MOSI lines + RegNVMAddr_t nvm_od; + nvm_od.r32 = 0xffffff; // All Input + nvm_od.bits.SCLKOutputDisable = 0; // Drive SCLK + nvm_od.bits.CSbOutputDisable = 0; // Drive CSb + nvm_od.bits.SIOutputDisable = 0; // Drive MOSI + + RegNVMWrite_t nvm_write; + + NVM.Addr.r32 = nvm_od.r32; + NVM.Write.r32 = nvm_write.r32; + // Enable Bitbang mode + NVM.NvmCfg1.r32 = cfg1_bitbang.r32; + + for (int i = 0; i < num_bytes; i++) + { + get_bytes[i] = NVRAM_sendAndGetByte(send_bytes[i]); + } + + // Restore Cfg1. + NVM.NvmCfg1.r32 = cfg1_orig.r32; + + NVRam_disable(); + NVRam_releaseLock(); + + return true; +} + +uint32_t NVRam_bitbang_readWord(uint32_t address) +{ + // 0x03: read word for AT45DB021D + uint8_t send_bytes[] = { + 0x03, (uint8_t)(address >> 16), (uint8_t)(address >> 8), (uint8_t)(address), 0x00, 0x00, 0x00, 0x00, + }; + uint8_t get_bytes[sizeof(send_bytes)]; + uint32_t num_bytes = sizeof(send_bytes); + NVRam_sendAndGetBytes(send_bytes, get_bytes, num_bytes); + + uint32_t read_word = (get_bytes[4]) | (get_bytes[5] << 8) | (get_bytes[6] << 16) | (get_bytes[7] << 24); + + return read_word; +} + +void NVRam_bitbang_writeWord(uint32_t address, uint32_t word) +{ + // 0x82: write word for AT45DB021D + uint8_t send_bytes[] = { 0x82, + (uint8_t)(address >> 16), + (uint8_t)(address >> 8), + (uint8_t)(address), + (uint8_t)(word >> 24), + (uint8_t)(word >> 16), + (uint8_t)(word >> 8), + (uint8_t)(word) }; + uint32_t num_bytes = sizeof(send_bytes); + NVRam_sendBytes(send_bytes, num_bytes); +} diff --git a/libs/NVRam/include/NVRam.h b/libs/NVRam/include/NVRam.h index 11a56b4..919aeb7 100644 --- a/libs/NVRam/include/NVRam.h +++ b/libs/NVRam/include/NVRam.h @@ -65,4 +65,14 @@ uint32_t NVRam_crc(const uint8_t *pcDatabuf, // Pointer to data buffer uint32_t ulDatalen, // Length of data buffer in bytes uint32_t crc); // Initial value +/** BitBang APIs **/ +void NVRAM_sendByte(uint8_t byte); +uint8_t NVRAM_sendAndGetByte(uint8_t byte); + +bool NVRam_sendBytes(uint8_t bytes[], uint32_t num_bytes); +bool NVRam_sendAndGetBytes(uint8_t send_bytes[], uint8_t get_bytes[], int32_t num_bytes); + +uint32_t NVRam_bitbang_readWord(uint32_t address); +void NVRam_bitbang_writeWord(uint32_t address, uint32_t word); + #endif /* NVRAM_H */ |