mirror of
https://github.com/stnolting/neorv32.git
synced 2025-04-24 22:27:21 -04:00
[sw/bootloader] TWI fix for bootloader (#1229)
This commit is contained in:
commit
9ab5f6225b
4 changed files with 73 additions and 20 deletions
|
@ -42,6 +42,11 @@
|
|||
#define UART_HW_HANDSHAKE_EN 0
|
||||
#endif
|
||||
|
||||
// Print splash screen
|
||||
#ifndef UART_PRINT_SPLASH_EN
|
||||
#define UART_PRINT_SPLASH_EN 1
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
* Status LED
|
||||
**********************************************************************/
|
||||
|
@ -120,7 +125,12 @@
|
|||
|
||||
// TWI clock divider
|
||||
#ifndef TWI_CLK_DIV
|
||||
#define TWI_CLK_DIV 1
|
||||
#define TWI_CLK_DIV 3
|
||||
#endif
|
||||
|
||||
// TWI allow clock stretching
|
||||
#ifndef TWI_CLK_STRECH_EN
|
||||
#define TWI_CLK_STRECH_EN 0
|
||||
#endif
|
||||
|
||||
// TWI device ID (write address; R/W cleared)
|
||||
|
@ -138,4 +148,9 @@
|
|||
#define TWI_FLASH_ADDR_BYTES 2
|
||||
#endif
|
||||
|
||||
// TWI flash bulk write enable
|
||||
#ifndef TWI_FLASH_BULK_WRITE_EN
|
||||
#define TWI_FLASH_BULK_WRITE_EN 0
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_H
|
||||
|
|
|
@ -18,5 +18,6 @@
|
|||
|
||||
int twi_flash_read_word(uint32_t addr, uint32_t* rdata);
|
||||
int twi_flash_write_word(uint32_t addr, uint32_t wdata);
|
||||
void twi_flash_delay_twi_tick(int tick_count);
|
||||
|
||||
#endif // TWI_FLASH_H
|
||||
|
|
|
@ -84,10 +84,10 @@ int twi_flash_read_word(uint32_t addr, uint32_t* rdata) {
|
|||
for (i = 0; i < 4; i++) {
|
||||
transfer = 0xFF;
|
||||
if (i == 3) {
|
||||
device_nack |= neorv32_twi_transfer(&transfer, 1); // NACK by host
|
||||
neorv32_twi_transfer(&transfer, 0); // NACK by host
|
||||
}
|
||||
else {
|
||||
neorv32_twi_transfer(&transfer, 0);
|
||||
neorv32_twi_transfer(&transfer, 1); // ACK by Host
|
||||
}
|
||||
data.uint8[i] = transfer;
|
||||
}
|
||||
|
@ -96,14 +96,10 @@ int twi_flash_read_word(uint32_t addr, uint32_t* rdata) {
|
|||
// send stop condition
|
||||
neorv32_twi_generate_stop();
|
||||
|
||||
if (device_nack) {
|
||||
neorv32_uart0_puts("\nTWI_R ERR\n");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
neorv32_uart0_puts("\nTWI_R OK\n");
|
||||
return 0;
|
||||
}
|
||||
// delay next read
|
||||
twi_flash_delay_twi_tick(1000);
|
||||
|
||||
return device_nack;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
|
@ -115,9 +111,10 @@ int twi_flash_read_word(uint32_t addr, uint32_t* rdata) {
|
|||
*
|
||||
* @param addr TWI flash write address.
|
||||
* @param wdata TWI flash write data.
|
||||
* @param stop Send TWI stop command at end of transmission
|
||||
* @return 0 if success, !=0 if error
|
||||
**************************************************************************/
|
||||
int twi_flash_write_byte(uint32_t addr, uint8_t wdata) {
|
||||
int twi_flash_write_byte(uint32_t addr, uint8_t wdata, int stop) {
|
||||
|
||||
int device_nack = 0;
|
||||
uint8_t transfer;
|
||||
|
@ -165,7 +162,13 @@ int twi_flash_write_byte(uint32_t addr, uint8_t wdata) {
|
|||
device_nack |= neorv32_twi_transfer(&transfer, 0);
|
||||
|
||||
// send stop condition
|
||||
neorv32_twi_generate_stop();
|
||||
if (stop) {
|
||||
neorv32_twi_generate_stop();
|
||||
|
||||
// delay next send for EEPROM write cycle
|
||||
neorv32_aux_delay_ms(NEORV32_SYSINFO->CLK,5); // t_wr(max) = 5ms
|
||||
}
|
||||
|
||||
|
||||
return device_nack;
|
||||
}
|
||||
|
@ -191,11 +194,28 @@ int twi_flash_write_word(uint32_t addr, uint32_t wdata) {
|
|||
|
||||
// write four bytes
|
||||
data.uint32 = wdata;
|
||||
device_nack += twi_flash_write_byte(addr+0, data.uint8[0]);
|
||||
device_nack += twi_flash_write_byte(addr+1, data.uint8[1]);
|
||||
device_nack += twi_flash_write_byte(addr+2, data.uint8[2]);
|
||||
device_nack += twi_flash_write_byte(addr+3, data.uint8[3]);
|
||||
#if(TWI_FLASH_BULK_WRITE_EN != 0)
|
||||
// send data
|
||||
uint8_t transfer = 0;
|
||||
device_nack += twi_flash_write_byte(addr, data.uint8[0], 0); // Start + addr + first byte
|
||||
transfer = data.uint8[1];
|
||||
device_nack += neorv32_twi_transfer(&transfer, 0);
|
||||
transfer = data.uint8[2];
|
||||
device_nack += neorv32_twi_transfer(&transfer, 0);
|
||||
transfer = data.uint8[3];
|
||||
device_nack += neorv32_twi_transfer(&transfer, 0);
|
||||
|
||||
// send stop condition
|
||||
neorv32_twi_generate_stop();
|
||||
|
||||
// delay next send for EEPROM write cycle
|
||||
neorv32_aux_delay_ms(NEORV32_SYSINFO->CLK,5); // t_wr(max) = 5ms
|
||||
#else
|
||||
device_nack += twi_flash_write_byte(addr+0, data.uint8[0], 1);
|
||||
device_nack += twi_flash_write_byte(addr+1, data.uint8[1], 1);
|
||||
device_nack += twi_flash_write_byte(addr+2, data.uint8[2], 1);
|
||||
device_nack += twi_flash_write_byte(addr+3, data.uint8[3], 1);
|
||||
#endif
|
||||
if (device_nack) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -206,3 +226,19 @@ int twi_flash_write_word(uint32_t addr, uint32_t wdata) {
|
|||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Keeps TWI Peripheral in IDLE for 'tick_count' TWI clock ticks
|
||||
*
|
||||
* @param tick_count Amount of TWI NOP ticks to wait
|
||||
*
|
||||
*/
|
||||
void twi_flash_delay_twi_tick(int tick_count){
|
||||
|
||||
for(int i = 0; i < tick_count; i++)
|
||||
{
|
||||
while (NEORV32_TWI->CTRL & (1<<TWI_CTRL_TX_FULL)); // wait for free TX entry
|
||||
NEORV32_TWI->DCMD = (uint32_t)(TWI_CMD_NOP << TWI_DCMD_CMD_LO); // IDLE for 1 twi tick
|
||||
}
|
||||
while (NEORV32_TWI->CTRL & (1 << TWI_CTRL_BUSY)); // wait until FIFO empty
|
||||
}
|
||||
|
|
|
@ -86,8 +86,8 @@ int main(void) {
|
|||
|
||||
// setup TWI
|
||||
#if (TWI_EN != 0)
|
||||
if (neorv32_uart0_available()) {
|
||||
neorv32_twi_available();
|
||||
if (neorv32_twi_available()) {
|
||||
neorv32_twi_setup(TWI_CLK_PRSC, TWI_CLK_DIV, TWI_CLK_STRECH_EN);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -104,7 +104,7 @@ int main(void) {
|
|||
// ------------------------------------------------
|
||||
// Splash screen
|
||||
// ------------------------------------------------
|
||||
|
||||
#if (UART_PRINT_SPLASH_EN != 0)
|
||||
uart_puts("\n\n\nNEORV32 Bootloader\n\n"
|
||||
"BLDV: "
|
||||
__DATE__
|
||||
|
@ -123,6 +123,7 @@ int main(void) {
|
|||
uart_puts("\nDMEM: ");
|
||||
uart_puth((uint32_t)(1 << NEORV32_SYSINFO->MISC[SYSINFO_MISC_DMEM]) & 0xFFFFFFFCU);
|
||||
uart_puts("\n\n");
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------
|
||||
// Auto boot sequence
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue