diff --git a/EVE_commands.c b/EVE_commands.c index 604fbd4..e22d7f7 100644 --- a/EVE_commands.c +++ b/EVE_commands.c @@ -2,7 +2,7 @@ @file EVE_commands.c @brief contains FT8xx / BT8xx functions @version 5.0 -@date 2021-12-27 +@date 2022-04-23 @author Rudolph Riedel @section info @@ -15,7 +15,7 @@ The c-standard is C99. MIT License -Copyright (c) 2016-2021 Rudolph Riedel +Copyright (c) 2016-2022 Rudolph Riedel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, @@ -159,6 +159,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH - finally removed EVE_cmd_start() after setting it to deprecatd with the first 5.0 release - renamed EVE_cmd_execute() to EVE_execute_cmd() to be more consistent, this is is not an EVE command - changed EVE_init_flash() to return E_OK in case of success and more meaningfull values in case of failure +- added the return-value of EVE_FIFO_HALF_EMPTY to EVE_busy() to indicate there is more than 2048 bytes available */ @@ -305,8 +306,9 @@ void EVE_memWrite_sram_buffer(uint32_t ftAddress, const uint8_t *data, uint32_t /** * @brief Check if the co-processor completed executing the current command list. * - * @return returns E_OK in case EVE is not busy (REG_CMDB_SPACE has the value 0xffc), - * returns EVE_IS_BUSY if a DMA transfer is active or REG_CMDB_SPACE has a value smaller than 0xffc + * @return returns E_OK in case EVE is not busy (no DMA transfer active and REG_CMDB_SPACE has the value 0xffc, meaning the CMD-FIFO is empty), + * returns EVE_FIFO_HALF_EMPTY if no DMA transfer is active and REG_CMDB_SPACE shows more than 2048 bytes available, + * returns EVE_IS_BUSY if a DMA transfer is active or REG_CMDB_SPACE has a value smaller than 0xffc, */ uint8_t EVE_busy(void) { @@ -357,8 +359,19 @@ uint8_t EVE_busy(void) #endif } - - return (space != 0xffc) ? EVE_IS_BUSY : E_OK; + + if(space == 0xffc) + { + return E_OK; + } + else if(space > 0x800) + { + return EVE_FIFO_HALF_EMPTY; + } + else + { + return EVE_IS_BUSY; + } } diff --git a/EVE_commands.h b/EVE_commands.h index 7c8aef7..1635136 100644 --- a/EVE_commands.h +++ b/EVE_commands.h @@ -2,14 +2,14 @@ @file EVE_commands.h @brief contains FT8xx / BT8xx function prototypes @version 5.0 -@date 2021-12-27 +@date 2022-04-23 @author Rudolph Riedel @section LICENSE MIT License -Copyright (c) 2016-2021 Rudolph Riedel +Copyright (c) 2016-2022 Rudolph Riedel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, @@ -81,6 +81,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH - added an enum with return codes to have the functions return something more meaningfull - finally removed EVE_cmd_start() after setting it to deprecatd with the first 5.0 release - renamed EVE_cmd_execute() to EVE_execute_cmd() to be more consistent, this is is not an EVE command +- added the return-value of EVE_FIFO_HALF_EMPTY to EVE_busy() to indicate there is more than 2048 bytes available */ @@ -106,7 +107,8 @@ enum EVE_FAIL_FLASHFAST_SECTOR0_FAILED, EVE_FAIL_FLASHFAST_BLOB_MISMATCH, EVE_FAIL_FLASHFAST_SPEED_TEST, - EVE_IS_BUSY + EVE_IS_BUSY, + EVE_FIFO_HALF_EMPTY }; diff --git a/EVE_target.c b/EVE_target.c index efe9b92..3db25e2 100644 --- a/EVE_target.c +++ b/EVE_target.c @@ -2,14 +2,14 @@ @file EVE_target.c @brief target specific functions for plain C targets @version 5.0 -@date 2021-12-04 +@date 2022-04-23 @author Rudolph Riedel @section LICENSE MIT License -Copyright (c) 2016-2021 Rudolph Riedel +Copyright (c) 2016-2022 Rudolph Riedel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, @@ -49,6 +49,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH - split up this file in EVE_target.c for the plain C targets and EVE_target.cpp for the Arduino C++ targets - converted all TABs to SPACEs - split the ATSAMC21 and ATSAMx51 targets into separate sections +- added more defines for ATSAMC21 and ATSAMx51 - chip crises... */ @@ -62,7 +63,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH /*----------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------*/ - #if defined (__SAMC21E18A__) || (__SAMC21J18A__) + #if defined (__SAMC21E18A__) || (__SAMC21J18A__) || (__SAMC21J17A__) || (__SAMC21J16A__) /* note: target as set by AtmelStudio, valid are all from the same family */ void DELAY_MS(uint16_t val) @@ -136,7 +137,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH /*----------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------*/ - #if defined (__SAME51J19A__) || (__SAMD51P20A__) || (__SAMD51J19A__) || (__SAMD51G18A__) + #if defined (__SAME51J19A__) || (__SAME51J18A__) || (__SAMD51P20A__) || (__SAMD51J19A__) || (__SAMD51G18A__) /* note: target as set by AtmelStudio, valid are all from the same family */ void DELAY_MS(uint16_t val) diff --git a/EVE_target.h b/EVE_target.h index 25db54a..f198953 100644 --- a/EVE_target.h +++ b/EVE_target.h @@ -2,14 +2,14 @@ @file EVE_target.h @brief target specific includes, definitions and functions @version 5.0 -@date 2021-12-27 +@date 2022-04-23 @author Rudolph Riedel @section LICENSE MIT License -Copyright (c) 2016-2021 Rudolph Riedel +Copyright (c) 2016-2022 Rudolph Riedel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, @@ -85,6 +85,8 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH - made the pin defines for all targets that have one optional - split the ATSAMC21 and ATSAMx51 targets into separate sections - updated the explanation of how DMA works +- added a TMS320F28335 target +- added more defines for ATSAMC21 and ATSAMx51 - chip crises... */ @@ -132,7 +134,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH while(val > 0) { - for(counter=0; counter < 2000;counter++) // maybe ~1ms at 16MHz clock + for(counter=0; counter < 2000;counter++) /* maybe ~1ms at 16MHz clock */ { __asm__ volatile ("nop"); } @@ -250,7 +252,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH static inline void spi_transmit(uint8_t data) { EVE_SPI.DATA = data; - while(!(EVE_SPI.STATUS & 0x80)) {}; // wait for transmit complete + while(!(EVE_SPI.STATUS & 0x80)) {}; /* wait for transmit complete */ } static inline void spi_transmit_32(uint32_t data) @@ -270,7 +272,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH static inline uint8_t spi_receive(uint8_t data) { EVE_SPI.DATA = data; - while(!(EVE_SPI.STATUS & 0x80)) {}; // wait for transmit complete + while(!(EVE_SPI.STATUS & 0x80)) {}; /* wait for transmit complete */ return EVE_SPI.DATA; } @@ -330,13 +332,13 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH SPDR = data; /* start transmission */ while(!(SPSR & (1<>= 1; @@ -378,9 +380,9 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH uint8_t spiInByte = 0; uint8_t k; - for(k = 0; k <8; k++) // Output each bit of spiOutByte + for(k = 0; k <8; k++) /* Output each bit of spiOutByte */ { - if(data & spiIndex) // Output MOSI Bit + if(data & spiIndex) /* Output MOSI Bit */ { PORTC |= (1< #if !defined (EVE_CS) #define EVE_CS_PORT 0 @@ -1088,12 +1089,12 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH static inline void EVE_cs_set(void) { - gpio_put(EVE_CS, 0); // active low + gpio_put(EVE_CS, 0); } static inline void EVE_cs_clear(void) { - gpio_put(EVE_CS, 1); // active high + gpio_put(EVE_CS, 1); } static inline void EVE_pdn_set(void) @@ -1405,13 +1406,13 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #if !defined (EVE_CS) #define RIVERDI_PORT GPIO_PORT_P1 - #define RIVERDI_SIMO BIT6 // P1.6 - #define RIVERDI_SOMI BIT7 // P1.7 - #define RIVERDI_CLK BIT5 // P1.5 + #define RIVERDI_SIMO BIT6 /* P1.6 */ + #define RIVERDI_SOMI BIT7 /* P1.7 */ + #define RIVERDI_CLK BIT5 /* P1.5 */ #define EVE_CS_PORT GPIO_PORT_P5 - #define EVE_CS GPIO_PIN0 //P5.0 + #define EVE_CS GPIO_PIN0 /* P5.0 */ #define EVE_PDN_PORT GPIO_PORT_P5 - #define EVE_PDN GPIO_PIN1 //P5.1 + #define EVE_PDN GPIO_PIN1 /* P5.1 */ #endif void EVE_SPI_Init(void); @@ -1422,7 +1423,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH while(val > 0) { - for(counter=0; counter < 8000;counter++) // ~1ms at 48MHz Core-Clock + for(counter=0; counter < 8000;counter++) /* ~1ms at 48MHz Core-Clock */ { __nop(); } @@ -1502,6 +1503,95 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #endif /* __TI_ARM */ #endif +/*----------------------------------------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------------------------------------*/ + +/* this is for TIs C2000 compiled with their ti-cgt-c2000 compiler which does not define this many symbols */ +#if defined (__TMS320C28XX__) + + /* the designated target actually is a TMS320F28335 */ + /* credit for this goes to David Sakal-Sega */ + /* note: the SPI unit of the TMS320F28335 does not support DMA, using one of the UARTs in SPI mode would allow DMA */ + + #include + #include + + typedef uint_least8_t uint8_t; /* this architecture does not actually know what a byte is, uint_least8_t is 16 bits wide */ + + /* 150MHz -> 6.67ns per cycle, 5 cycles for the loop itself and 8 NOPs -> 1ms / (6.67ns * 13) = 11532 */ + #define EVE_DELAY_1MS 12000 + + static inline void DELAY_MS(uint16_t val) + { + uint16_t counter; + + while(val > 0) + { + for(counter=0; counter < EVE_DELAY_1MS;counter++) + { + asm(" RPT #7 || NOP"); + } + val--; + } + } + + static inline void EVE_pdn_set(void) + { + GpioDataRegs.GPACLEAR.bit.GPIO14 = 1; /* Power-Down low */ + } + + static inline void EVE_pdn_clear(void) + { + GpioDataRegs.GPASET.bit.GPIO14 = 1; /* Power-Down high */ + } + + static inline void EVE_cs_set(void) + { + GpioDataRegs.GPACLEAR.bit.GPIO19 = 1; /* CS low */ + } + + static inline void EVE_cs_clear(void) + { + asm(" RPT #60 || NOP"); /* wait 60 cycles to make sure CS is not going high too early */ + GpioDataRegs.GPASET.bit.GPIO19 = 1; /* CS high */ + } + + static inline void spi_transmit(uint8_t data) + { + SpiaRegs.SPITXBUF = (data & 0xFF) << 8; /* start transfer, looks odd with data = uint8_t but uint8_t actually is 16 bits wide on this controller */ + while(SpiaRegs.SPISTS.bit.INT_FLAG == 0); /* wait for transmission to complete */ + (void) SpiaRegs.SPIRXBUF; /* dummy read to clear the flags */ + } + + static inline void spi_transmit_32(uint32_t data) + { + spi_transmit((uint8_t)(data & 0x000000ff)); + spi_transmit((uint8_t)(data >> 8)); + spi_transmit((uint8_t)(data >> 16)); + spi_transmit((uint8_t)(data >> 24)); + } + + /* spi_transmit_burst() is only used for cmd-FIFO commands so it *always* has to transfer 4 bytes */ + static inline void spi_transmit_burst(uint32_t data) + { + spi_transmit_32(data); + } + + static inline uint8_t spi_receive(uint8_t data) + { + SpiaRegs.SPITXBUF = (data & 0xFF) << 8; /* start transfer */ + while(SpiaRegs.SPISTS.bit.INT_FLAG == 0); /* wait for transmission to complete */ + return (SpiaRegs.SPIRXBUF & 0x00FF); /* data is right justified in SPIRXBUF */ + } + + static inline uint8_t fetch_flash_byte(const uint8_t *data) + { + return *data; + } + +#endif + + /*----------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------*/ diff --git a/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/EVE_commands.c b/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/EVE_commands.c index dc36d8a..3b22ec8 100644 --- a/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/EVE_commands.c +++ b/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/EVE_commands.c @@ -2,7 +2,7 @@ @file EVE_commands.c @brief contains FT8xx / BT8xx functions @version 5.0 -@date 2021-12-27 +@date 2022-04-23 @author Rudolph Riedel @section info @@ -15,7 +15,7 @@ The c-standard is C99. MIT License -Copyright (c) 2016-2021 Rudolph Riedel +Copyright (c) 2016-2022 Rudolph Riedel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, @@ -159,6 +159,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH - finally removed EVE_cmd_start() after setting it to deprecatd with the first 5.0 release - renamed EVE_cmd_execute() to EVE_execute_cmd() to be more consistent, this is is not an EVE command - changed EVE_init_flash() to return E_OK in case of success and more meaningfull values in case of failure +- added the return-value of EVE_FIFO_HALF_EMPTY to EVE_busy() to indicate there is more than 2048 bytes available */ @@ -305,8 +306,9 @@ void EVE_memWrite_sram_buffer(uint32_t ftAddress, const uint8_t *data, uint32_t /** * @brief Check if the co-processor completed executing the current command list. * - * @return returns E_OK in case EVE is not busy (REG_CMDB_SPACE has the value 0xffc), - * returns EVE_IS_BUSY if a DMA transfer is active or REG_CMDB_SPACE has a value smaller than 0xffc + * @return returns E_OK in case EVE is not busy (no DMA transfer active and REG_CMDB_SPACE has the value 0xffc, meaning the CMD-FIFO is empty), + * returns EVE_FIFO_HALF_EMPTY if no DMA transfer is active and REG_CMDB_SPACE shows more than 2048 bytes available, + * returns EVE_IS_BUSY if a DMA transfer is active or REG_CMDB_SPACE has a value smaller than 0xffc, */ uint8_t EVE_busy(void) { @@ -357,8 +359,19 @@ uint8_t EVE_busy(void) #endif } - - return (space != 0xffc) ? EVE_IS_BUSY : E_OK; + + if(space == 0xffc) + { + return E_OK; + } + else if(space > 0x800) + { + return EVE_FIFO_HALF_EMPTY; + } + else + { + return EVE_IS_BUSY; + } } diff --git a/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/EVE_commands.h b/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/EVE_commands.h index a273f2d..a2a70fc 100644 --- a/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/EVE_commands.h +++ b/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/EVE_commands.h @@ -2,14 +2,14 @@ @file EVE_commands.h @brief contains FT8xx / BT8xx function prototypes @version 5.0 -@date 2021-12-27 +@date 2022-04-23 @author Rudolph Riedel @section LICENSE MIT License -Copyright (c) 2016-2021 Rudolph Riedel +Copyright (c) 2016-2022 Rudolph Riedel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, @@ -81,6 +81,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH - added an enum with return codes to have the functions return something more meaningfull - finally removed EVE_cmd_start() after setting it to deprecatd with the first 5.0 release - renamed EVE_cmd_execute() to EVE_execute_cmd() to be more consistent, this is is not an EVE command +- added the return-value of EVE_FIFO_HALF_EMPTY to EVE_busy() to indicate there is more than 2048 bytes available */ @@ -106,7 +107,8 @@ enum EVE_FAIL_FLASHFAST_SECTOR0_FAILED, EVE_FAIL_FLASHFAST_BLOB_MISMATCH, EVE_FAIL_FLASHFAST_SPEED_TEST, - EVE_IS_BUSY + EVE_IS_BUSY, + EVE_FIFO_HALF_EMPTY }; diff --git a/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/EVE_target.c b/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/EVE_target.c index fc3ee20..d98c64e 100644 --- a/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/EVE_target.c +++ b/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/EVE_target.c @@ -2,14 +2,14 @@ @file EVE_target.c @brief target specific functions for plain C targets @version 5.0 -@date 2021-12-04 +@date 2022-04-23 @author Rudolph Riedel @section LICENSE MIT License -Copyright (c) 2016-2021 Rudolph Riedel +Copyright (c) 2016-2022 Rudolph Riedel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, @@ -49,6 +49,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH - split up this file in EVE_target.c for the plain C targets and EVE_target.cpp for the Arduino C++ targets - converted all TABs to SPACEs - split the ATSAMC21 and ATSAMx51 targets into separate sections +- added more defines for ATSAMC21 and ATSAMx51 - chip crises... */ @@ -62,7 +63,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH /*----------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------*/ - #if defined (__SAMC21E18A__) || (__SAMC21J18A__) + #if defined (__SAMC21E18A__) || (__SAMC21J18A__) || (__SAMC21J17A__) || (__SAMC21J16A__) /* note: target as set by AtmelStudio, valid are all from the same family */ void DELAY_MS(uint16_t val) @@ -136,7 +137,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH /*----------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------*/ - #if defined (__SAME51J19A__) || (__SAMD51P20A__) || (__SAMD51J19A__) || (__SAMD51G18A__) + #if defined (__SAME51J19A__) || (__SAME51J18A__) || (__SAMD51P20A__) || (__SAMD51J19A__) || (__SAMD51G18A__) /* note: target as set by AtmelStudio, valid are all from the same family */ void DELAY_MS(uint16_t val) diff --git a/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/EVE_target.h b/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/EVE_target.h index 75ac1da..a75292a 100644 --- a/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/EVE_target.h +++ b/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/EVE_target.h @@ -2,14 +2,14 @@ @file EVE_target.h @brief target specific includes, definitions and functions @version 5.0 -@date 2021-12-27 +@date 2022-04-23 @author Rudolph Riedel @section LICENSE MIT License -Copyright (c) 2016-2021 Rudolph Riedel +Copyright (c) 2016-2022 Rudolph Riedel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, @@ -85,6 +85,8 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH - made the pin defines for all targets that have one optional - split the ATSAMC21 and ATSAMx51 targets into separate sections - updated the explanation of how DMA works +- added a TMS320F28335 target +- added more defines for ATSAMC21 and ATSAMx51 - chip crises... */ @@ -132,7 +134,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH while(val > 0) { - for(counter=0; counter < 2000;counter++) // maybe ~1ms at 16MHz clock + for(counter=0; counter < 2000;counter++) /* maybe ~1ms at 16MHz clock */ { __asm__ volatile ("nop"); } @@ -250,7 +252,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH static inline void spi_transmit(uint8_t data) { EVE_SPI.DATA = data; - while(!(EVE_SPI.STATUS & 0x80)) {}; // wait for transmit complete + while(!(EVE_SPI.STATUS & 0x80)) {}; /* wait for transmit complete */ } static inline void spi_transmit_32(uint32_t data) @@ -270,7 +272,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH static inline uint8_t spi_receive(uint8_t data) { EVE_SPI.DATA = data; - while(!(EVE_SPI.STATUS & 0x80)) {}; // wait for transmit complete + while(!(EVE_SPI.STATUS & 0x80)) {}; /* wait for transmit complete */ return EVE_SPI.DATA; } @@ -330,13 +332,13 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH SPDR = data; /* start transmission */ while(!(SPSR & (1<>= 1; @@ -378,9 +380,9 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH uint8_t spiInByte = 0; uint8_t k; - for(k = 0; k <8; k++) // Output each bit of spiOutByte + for(k = 0; k <8; k++) /* Output each bit of spiOutByte */ { - if(data & spiIndex) // Output MOSI Bit + if(data & spiIndex) /* Output MOSI Bit */ { PORTC |= (1< #if !defined (EVE_CS) #define EVE_CS_PORT 0 @@ -1088,12 +1089,12 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH static inline void EVE_cs_set(void) { - gpio_put(EVE_CS, 0); // active low + gpio_put(EVE_CS, 0); } static inline void EVE_cs_clear(void) { - gpio_put(EVE_CS, 1); // active high + gpio_put(EVE_CS, 1); } static inline void EVE_pdn_set(void) @@ -1405,13 +1406,13 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #if !defined (EVE_CS) #define RIVERDI_PORT GPIO_PORT_P1 - #define RIVERDI_SIMO BIT6 // P1.6 - #define RIVERDI_SOMI BIT7 // P1.7 - #define RIVERDI_CLK BIT5 // P1.5 + #define RIVERDI_SIMO BIT6 /* P1.6 */ + #define RIVERDI_SOMI BIT7 /* P1.7 */ + #define RIVERDI_CLK BIT5 /* P1.5 */ #define EVE_CS_PORT GPIO_PORT_P5 - #define EVE_CS GPIO_PIN0 //P5.0 + #define EVE_CS GPIO_PIN0 /* P5.0 */ #define EVE_PDN_PORT GPIO_PORT_P5 - #define EVE_PDN GPIO_PIN1 //P5.1 + #define EVE_PDN GPIO_PIN1 /* P5.1 */ #endif void EVE_SPI_Init(void); @@ -1422,7 +1423,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH while(val > 0) { - for(counter=0; counter < 8000;counter++) // ~1ms at 48MHz Core-Clock + for(counter=0; counter < 8000;counter++) /* ~1ms at 48MHz Core-Clock */ { __nop(); } @@ -1502,6 +1503,95 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #endif /* __TI_ARM */ #endif +/*----------------------------------------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------------------------------------*/ + +/* this is for TIs C2000 compiled with their ti-cgt-c2000 compiler which does not define this many symbols */ +#if defined (__TMS320C28XX__) + + /* the designated target actually is a TMS320F28335 */ + /* credit for this goes to David Sakal-Sega */ + /* note: the SPI unit of the TMS320F28335 does not support DMA, using one of the UARTs in SPI mode would allow DMA */ + + #include + #include + + typedef uint_least8_t uint8_t; /* this architecture does not actually know what a byte is, uint_least8_t is 16 bits wide */ + + /* 150MHz -> 6.67ns per cycle, 5 cycles for the loop itself and 8 NOPs -> 1ms / (6.67ns * 13) = 11532 */ + #define EVE_DELAY_1MS 12000 + + static inline void DELAY_MS(uint16_t val) + { + uint16_t counter; + + while(val > 0) + { + for(counter=0; counter < EVE_DELAY_1MS;counter++) + { + asm(" RPT #7 || NOP"); + } + val--; + } + } + + static inline void EVE_pdn_set(void) + { + GpioDataRegs.GPACLEAR.bit.GPIO14 = 1; /* Power-Down low */ + } + + static inline void EVE_pdn_clear(void) + { + GpioDataRegs.GPASET.bit.GPIO14 = 1; /* Power-Down high */ + } + + static inline void EVE_cs_set(void) + { + GpioDataRegs.GPACLEAR.bit.GPIO19 = 1; /* CS low */ + } + + static inline void EVE_cs_clear(void) + { + asm(" RPT #60 || NOP"); /* wait 60 cycles to make sure CS is not going high too early */ + GpioDataRegs.GPASET.bit.GPIO19 = 1; /* CS high */ + } + + static inline void spi_transmit(uint8_t data) + { + SpiaRegs.SPITXBUF = (data & 0xFF) << 8; /* start transfer, looks odd with data = uint8_t but uint8_t actually is 16 bits wide on this controller */ + while(SpiaRegs.SPISTS.bit.INT_FLAG == 0); /* wait for transmission to complete */ + (void) SpiaRegs.SPIRXBUF; /* dummy read to clear the flags */ + } + + static inline void spi_transmit_32(uint32_t data) + { + spi_transmit((uint8_t)(data & 0x000000ff)); + spi_transmit((uint8_t)(data >> 8)); + spi_transmit((uint8_t)(data >> 16)); + spi_transmit((uint8_t)(data >> 24)); + } + + /* spi_transmit_burst() is only used for cmd-FIFO commands so it *always* has to transfer 4 bytes */ + static inline void spi_transmit_burst(uint32_t data) + { + spi_transmit_32(data); + } + + static inline uint8_t spi_receive(uint8_t data) + { + SpiaRegs.SPITXBUF = (data & 0xFF) << 8; /* start transfer */ + while(SpiaRegs.SPISTS.bit.INT_FLAG == 0); /* wait for transmission to complete */ + return (SpiaRegs.SPIRXBUF & 0x00FF); /* data is right justified in SPIRXBUF */ + } + + static inline uint8_t fetch_flash_byte(const uint8_t *data) + { + return *data; + } + +#endif + + /*----------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------*/ diff --git a/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/README.md b/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/README.md index 5e308b4..f7305d6 100644 --- a/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/README.md +++ b/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/README.md @@ -72,7 +72,7 @@ FT810, FT811, FT812, FT813, BT815, BT816, BT817 and BT818 can use the exact same As a side effect all commands are automatically started now. Second is that there are two sets of display-list building command functions now: EVE_cmd_xxx() and EVE_cmd_xxx_burst(). -The EVE_cmd_xxx_burst() functions are optimised for speed, these are pure data transfer functions and do not even check anymore if burst mode is active. +The EVE_cmd_xxx_burst() functions are optimized for speed, these are pure data transfer functions and do not even check anymore if burst mode is active. ## Structure @@ -119,19 +119,78 @@ while (EVE_busy()); ```` This does the same as the first example but faster. -The trailing EVE_start_cmd_burst() either sets chip-select to low and sends out the three byte address. +The preceding EVE_start_cmd_burst() either sets chip-select to low and sends out the three byte address. Or if DMA is available for the target you are compiling for with support code in EVE_target.c / EVE_target.cpp and EVE_target.h, it writes the address to EVE_dma_buffer and sets EVE_dma_buffer_index to 1. Note the trailing "_burst" in the following functions, these are special versions of these commands that can only be used within an EVE_start_cmd_burst()/EVE_end_cmd_bust() pair. -These functions are optimised to push out data and nothing else. +These functions are optimized to push out data and nothing else. -The final EVE_end_cmd_bust() either pulls back the chip-select to high. +The final EVE_end_cmd_burst() either pulls back the chip-select to high. Or if we have DMA it calls EVE_start_dma_transfer() to start pushing out the buffer in the background. As we have 7 commands for EVE in these simple examples, the second one has the address overhead removed from six commands and therefore needs to transfer 18 bytes less over SPI. -So even with a small 8-bit controller that does not support DMA this is a usefull optimisation for building display lists. +So even with a small 8-bit controller that does not support DMA this is a usefull optimization for building display lists. Using DMA has one caveat: we need to limit the transfer to <4k as we are writing to the FIFO of EVEs command co-processor. This is usually not an issue though as we can shorten the display list generation with previously generated snippets that we attach to the current list with CMD_APPEND. And when we use widgets like CMD_BUTTON or CMD_CLOCK the generated display list grows by a larger amount than what we need to put into the command-FIFO so we likely reach the 8k limit of the display-list before we hit the 4k limit of the command-FIFO. +It is possible to use two or more DMA transfers to the FIFO to build a single display list, either to get around the 4k limit of the FIFO or in order to distribute the workload better of the time necessary between two display renewals. + +You could for example do this, spread over three consecutive calls: +```` +EVE_start_cmd_burst(); +EVE_cmd_dl_burst(CMD_DLSTART); +EVE_cmd_dl_burst(DL_CLEAR_RGB | WHITE); +EVE_end_cmd_burst(); +```` + +```` +EVE_start_cmd_burst(); +EVE_cmd_dl_burst(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG); +EVE_color_rgb_burst(BLACK); +EVE_end_cmd_burst(); +```` + +```` +EVE_start_cmd_burst(); +EVE_cmd_text_burst(5, 15, 28, 0, "Hello there!"); +EVE_cmd_dl_burst(DL_DISPLAY); +EVE_cmd_dl_burst(CMD_SWAP); +EVE_end_cmd_burst(); +```` + +But you need to check with EVE_busy() before each of these blocks. +Maybe similar like this never compiled pseudo-code: + +thread_1ms_update_display() +{ + static uint8_t state = 0; + static uint8_t count = 0; + + count++; + + if(EVE_busy() == E_OK) + { + switch(state) + { + case 0: + update_first(); + state = 1; + break; + case 1: + update_second(); + state = 2; + break; + case 2: + if(counter > 19) + { + update_last_swap_list(); + count = 0; + state = 0; + } + break; + } + } +} + ## Remarks @@ -145,19 +204,19 @@ There is a list of available options at the start of EVE_config.h sorted by chip - Provide the pins used for Chip-Select and Power-Down in EVE_target.h for the target configuration you are using -When compiling for AVR you need to provide the clock it is running at in order to make the _delay_ms() calls used to initialise the TFT work with the intended timing. +When compiling for AVR you need to provide the clock it is running at in order to make the _delay_ms() calls used to initialize the TFT work with the intended timing. For other plattforms you need to provide a DELAY_MS(ms) function that works at least between 1ms and 56ms and is not performing these delays shorter than requested. The DELAY_MS(ms) is only used during initialization of the FT8xx/BT8xx. See EVE_target.h for examples. -In Addition you need to initialise the pins used for Chip-Select and PowerDown in your hardware correctly to output. +In Addition you need to initialize the pins used for Chip-Select and Power-Down in your hardware correctly to output. Plus setup the SPI accordingly, mode-0, 8-bit, MSB-first, not more than 11MHz for the init. A couple of targets already have a function EVE_init_spi() in EVE_target.c. A word of "warning", you have to take a little care yourself to for example not send more than 4kB at once to the command co-processor or to not generate display lists that are longer than 8kB. My library does not check and re-check the command-FIFO on every step. -This is optimised for speed so the training wheels are off. +This is optimized for speed, so the training wheels are off. ## Post questions here diff --git a/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/library.json b/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/library.json index d1ace70..278b2ff 100644 --- a/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/library.json +++ b/examples/EVE_Test_SAMC21_EVE2-50G/EmbeddedVideoEngine/library.json @@ -1,6 +1,6 @@ { "name": "EmbeddedVideoEngine", - "version": "5.0.3", + "version": "5.0.4", "keywords": "TFT, SPI, EVE2, EVE3, EVE4 ,Bridgetek, F81x, FT813, BT81x, BT815, BT817", "description": "Code library for EVE2/EVE3/EVE4 graphics controller ICs from FTDI/Bridgetek", "repository": { diff --git a/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/EVE_commands.c b/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/EVE_commands.c index dc36d8a..3b22ec8 100644 --- a/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/EVE_commands.c +++ b/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/EVE_commands.c @@ -2,7 +2,7 @@ @file EVE_commands.c @brief contains FT8xx / BT8xx functions @version 5.0 -@date 2021-12-27 +@date 2022-04-23 @author Rudolph Riedel @section info @@ -15,7 +15,7 @@ The c-standard is C99. MIT License -Copyright (c) 2016-2021 Rudolph Riedel +Copyright (c) 2016-2022 Rudolph Riedel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, @@ -159,6 +159,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH - finally removed EVE_cmd_start() after setting it to deprecatd with the first 5.0 release - renamed EVE_cmd_execute() to EVE_execute_cmd() to be more consistent, this is is not an EVE command - changed EVE_init_flash() to return E_OK in case of success and more meaningfull values in case of failure +- added the return-value of EVE_FIFO_HALF_EMPTY to EVE_busy() to indicate there is more than 2048 bytes available */ @@ -305,8 +306,9 @@ void EVE_memWrite_sram_buffer(uint32_t ftAddress, const uint8_t *data, uint32_t /** * @brief Check if the co-processor completed executing the current command list. * - * @return returns E_OK in case EVE is not busy (REG_CMDB_SPACE has the value 0xffc), - * returns EVE_IS_BUSY if a DMA transfer is active or REG_CMDB_SPACE has a value smaller than 0xffc + * @return returns E_OK in case EVE is not busy (no DMA transfer active and REG_CMDB_SPACE has the value 0xffc, meaning the CMD-FIFO is empty), + * returns EVE_FIFO_HALF_EMPTY if no DMA transfer is active and REG_CMDB_SPACE shows more than 2048 bytes available, + * returns EVE_IS_BUSY if a DMA transfer is active or REG_CMDB_SPACE has a value smaller than 0xffc, */ uint8_t EVE_busy(void) { @@ -357,8 +359,19 @@ uint8_t EVE_busy(void) #endif } - - return (space != 0xffc) ? EVE_IS_BUSY : E_OK; + + if(space == 0xffc) + { + return E_OK; + } + else if(space > 0x800) + { + return EVE_FIFO_HALF_EMPTY; + } + else + { + return EVE_IS_BUSY; + } } diff --git a/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/EVE_commands.h b/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/EVE_commands.h index a273f2d..a2a70fc 100644 --- a/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/EVE_commands.h +++ b/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/EVE_commands.h @@ -2,14 +2,14 @@ @file EVE_commands.h @brief contains FT8xx / BT8xx function prototypes @version 5.0 -@date 2021-12-27 +@date 2022-04-23 @author Rudolph Riedel @section LICENSE MIT License -Copyright (c) 2016-2021 Rudolph Riedel +Copyright (c) 2016-2022 Rudolph Riedel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, @@ -81,6 +81,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH - added an enum with return codes to have the functions return something more meaningfull - finally removed EVE_cmd_start() after setting it to deprecatd with the first 5.0 release - renamed EVE_cmd_execute() to EVE_execute_cmd() to be more consistent, this is is not an EVE command +- added the return-value of EVE_FIFO_HALF_EMPTY to EVE_busy() to indicate there is more than 2048 bytes available */ @@ -106,7 +107,8 @@ enum EVE_FAIL_FLASHFAST_SECTOR0_FAILED, EVE_FAIL_FLASHFAST_BLOB_MISMATCH, EVE_FAIL_FLASHFAST_SPEED_TEST, - EVE_IS_BUSY + EVE_IS_BUSY, + EVE_FIFO_HALF_EMPTY }; diff --git a/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/EVE_target.c b/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/EVE_target.c index fc3ee20..d98c64e 100644 --- a/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/EVE_target.c +++ b/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/EVE_target.c @@ -2,14 +2,14 @@ @file EVE_target.c @brief target specific functions for plain C targets @version 5.0 -@date 2021-12-04 +@date 2022-04-23 @author Rudolph Riedel @section LICENSE MIT License -Copyright (c) 2016-2021 Rudolph Riedel +Copyright (c) 2016-2022 Rudolph Riedel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, @@ -49,6 +49,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH - split up this file in EVE_target.c for the plain C targets and EVE_target.cpp for the Arduino C++ targets - converted all TABs to SPACEs - split the ATSAMC21 and ATSAMx51 targets into separate sections +- added more defines for ATSAMC21 and ATSAMx51 - chip crises... */ @@ -62,7 +63,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH /*----------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------*/ - #if defined (__SAMC21E18A__) || (__SAMC21J18A__) + #if defined (__SAMC21E18A__) || (__SAMC21J18A__) || (__SAMC21J17A__) || (__SAMC21J16A__) /* note: target as set by AtmelStudio, valid are all from the same family */ void DELAY_MS(uint16_t val) @@ -136,7 +137,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH /*----------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------*/ - #if defined (__SAME51J19A__) || (__SAMD51P20A__) || (__SAMD51J19A__) || (__SAMD51G18A__) + #if defined (__SAME51J19A__) || (__SAME51J18A__) || (__SAMD51P20A__) || (__SAMD51J19A__) || (__SAMD51G18A__) /* note: target as set by AtmelStudio, valid are all from the same family */ void DELAY_MS(uint16_t val) diff --git a/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/EVE_target.h b/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/EVE_target.h index 75ac1da..a75292a 100644 --- a/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/EVE_target.h +++ b/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/EVE_target.h @@ -2,14 +2,14 @@ @file EVE_target.h @brief target specific includes, definitions and functions @version 5.0 -@date 2021-12-27 +@date 2022-04-23 @author Rudolph Riedel @section LICENSE MIT License -Copyright (c) 2016-2021 Rudolph Riedel +Copyright (c) 2016-2022 Rudolph Riedel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, @@ -85,6 +85,8 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH - made the pin defines for all targets that have one optional - split the ATSAMC21 and ATSAMx51 targets into separate sections - updated the explanation of how DMA works +- added a TMS320F28335 target +- added more defines for ATSAMC21 and ATSAMx51 - chip crises... */ @@ -132,7 +134,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH while(val > 0) { - for(counter=0; counter < 2000;counter++) // maybe ~1ms at 16MHz clock + for(counter=0; counter < 2000;counter++) /* maybe ~1ms at 16MHz clock */ { __asm__ volatile ("nop"); } @@ -250,7 +252,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH static inline void spi_transmit(uint8_t data) { EVE_SPI.DATA = data; - while(!(EVE_SPI.STATUS & 0x80)) {}; // wait for transmit complete + while(!(EVE_SPI.STATUS & 0x80)) {}; /* wait for transmit complete */ } static inline void spi_transmit_32(uint32_t data) @@ -270,7 +272,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH static inline uint8_t spi_receive(uint8_t data) { EVE_SPI.DATA = data; - while(!(EVE_SPI.STATUS & 0x80)) {}; // wait for transmit complete + while(!(EVE_SPI.STATUS & 0x80)) {}; /* wait for transmit complete */ return EVE_SPI.DATA; } @@ -330,13 +332,13 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH SPDR = data; /* start transmission */ while(!(SPSR & (1<>= 1; @@ -378,9 +380,9 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH uint8_t spiInByte = 0; uint8_t k; - for(k = 0; k <8; k++) // Output each bit of spiOutByte + for(k = 0; k <8; k++) /* Output each bit of spiOutByte */ { - if(data & spiIndex) // Output MOSI Bit + if(data & spiIndex) /* Output MOSI Bit */ { PORTC |= (1< #if !defined (EVE_CS) #define EVE_CS_PORT 0 @@ -1088,12 +1089,12 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH static inline void EVE_cs_set(void) { - gpio_put(EVE_CS, 0); // active low + gpio_put(EVE_CS, 0); } static inline void EVE_cs_clear(void) { - gpio_put(EVE_CS, 1); // active high + gpio_put(EVE_CS, 1); } static inline void EVE_pdn_set(void) @@ -1405,13 +1406,13 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #if !defined (EVE_CS) #define RIVERDI_PORT GPIO_PORT_P1 - #define RIVERDI_SIMO BIT6 // P1.6 - #define RIVERDI_SOMI BIT7 // P1.7 - #define RIVERDI_CLK BIT5 // P1.5 + #define RIVERDI_SIMO BIT6 /* P1.6 */ + #define RIVERDI_SOMI BIT7 /* P1.7 */ + #define RIVERDI_CLK BIT5 /* P1.5 */ #define EVE_CS_PORT GPIO_PORT_P5 - #define EVE_CS GPIO_PIN0 //P5.0 + #define EVE_CS GPIO_PIN0 /* P5.0 */ #define EVE_PDN_PORT GPIO_PORT_P5 - #define EVE_PDN GPIO_PIN1 //P5.1 + #define EVE_PDN GPIO_PIN1 /* P5.1 */ #endif void EVE_SPI_Init(void); @@ -1422,7 +1423,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH while(val > 0) { - for(counter=0; counter < 8000;counter++) // ~1ms at 48MHz Core-Clock + for(counter=0; counter < 8000;counter++) /* ~1ms at 48MHz Core-Clock */ { __nop(); } @@ -1502,6 +1503,95 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #endif /* __TI_ARM */ #endif +/*----------------------------------------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------------------------------------*/ + +/* this is for TIs C2000 compiled with their ti-cgt-c2000 compiler which does not define this many symbols */ +#if defined (__TMS320C28XX__) + + /* the designated target actually is a TMS320F28335 */ + /* credit for this goes to David Sakal-Sega */ + /* note: the SPI unit of the TMS320F28335 does not support DMA, using one of the UARTs in SPI mode would allow DMA */ + + #include + #include + + typedef uint_least8_t uint8_t; /* this architecture does not actually know what a byte is, uint_least8_t is 16 bits wide */ + + /* 150MHz -> 6.67ns per cycle, 5 cycles for the loop itself and 8 NOPs -> 1ms / (6.67ns * 13) = 11532 */ + #define EVE_DELAY_1MS 12000 + + static inline void DELAY_MS(uint16_t val) + { + uint16_t counter; + + while(val > 0) + { + for(counter=0; counter < EVE_DELAY_1MS;counter++) + { + asm(" RPT #7 || NOP"); + } + val--; + } + } + + static inline void EVE_pdn_set(void) + { + GpioDataRegs.GPACLEAR.bit.GPIO14 = 1; /* Power-Down low */ + } + + static inline void EVE_pdn_clear(void) + { + GpioDataRegs.GPASET.bit.GPIO14 = 1; /* Power-Down high */ + } + + static inline void EVE_cs_set(void) + { + GpioDataRegs.GPACLEAR.bit.GPIO19 = 1; /* CS low */ + } + + static inline void EVE_cs_clear(void) + { + asm(" RPT #60 || NOP"); /* wait 60 cycles to make sure CS is not going high too early */ + GpioDataRegs.GPASET.bit.GPIO19 = 1; /* CS high */ + } + + static inline void spi_transmit(uint8_t data) + { + SpiaRegs.SPITXBUF = (data & 0xFF) << 8; /* start transfer, looks odd with data = uint8_t but uint8_t actually is 16 bits wide on this controller */ + while(SpiaRegs.SPISTS.bit.INT_FLAG == 0); /* wait for transmission to complete */ + (void) SpiaRegs.SPIRXBUF; /* dummy read to clear the flags */ + } + + static inline void spi_transmit_32(uint32_t data) + { + spi_transmit((uint8_t)(data & 0x000000ff)); + spi_transmit((uint8_t)(data >> 8)); + spi_transmit((uint8_t)(data >> 16)); + spi_transmit((uint8_t)(data >> 24)); + } + + /* spi_transmit_burst() is only used for cmd-FIFO commands so it *always* has to transfer 4 bytes */ + static inline void spi_transmit_burst(uint32_t data) + { + spi_transmit_32(data); + } + + static inline uint8_t spi_receive(uint8_t data) + { + SpiaRegs.SPITXBUF = (data & 0xFF) << 8; /* start transfer */ + while(SpiaRegs.SPISTS.bit.INT_FLAG == 0); /* wait for transmission to complete */ + return (SpiaRegs.SPIRXBUF & 0x00FF); /* data is right justified in SPIRXBUF */ + } + + static inline uint8_t fetch_flash_byte(const uint8_t *data) + { + return *data; + } + +#endif + + /*----------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------*/ diff --git a/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/README.md b/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/README.md index 5e308b4..f7305d6 100644 --- a/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/README.md +++ b/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/README.md @@ -72,7 +72,7 @@ FT810, FT811, FT812, FT813, BT815, BT816, BT817 and BT818 can use the exact same As a side effect all commands are automatically started now. Second is that there are two sets of display-list building command functions now: EVE_cmd_xxx() and EVE_cmd_xxx_burst(). -The EVE_cmd_xxx_burst() functions are optimised for speed, these are pure data transfer functions and do not even check anymore if burst mode is active. +The EVE_cmd_xxx_burst() functions are optimized for speed, these are pure data transfer functions and do not even check anymore if burst mode is active. ## Structure @@ -119,19 +119,78 @@ while (EVE_busy()); ```` This does the same as the first example but faster. -The trailing EVE_start_cmd_burst() either sets chip-select to low and sends out the three byte address. +The preceding EVE_start_cmd_burst() either sets chip-select to low and sends out the three byte address. Or if DMA is available for the target you are compiling for with support code in EVE_target.c / EVE_target.cpp and EVE_target.h, it writes the address to EVE_dma_buffer and sets EVE_dma_buffer_index to 1. Note the trailing "_burst" in the following functions, these are special versions of these commands that can only be used within an EVE_start_cmd_burst()/EVE_end_cmd_bust() pair. -These functions are optimised to push out data and nothing else. +These functions are optimized to push out data and nothing else. -The final EVE_end_cmd_bust() either pulls back the chip-select to high. +The final EVE_end_cmd_burst() either pulls back the chip-select to high. Or if we have DMA it calls EVE_start_dma_transfer() to start pushing out the buffer in the background. As we have 7 commands for EVE in these simple examples, the second one has the address overhead removed from six commands and therefore needs to transfer 18 bytes less over SPI. -So even with a small 8-bit controller that does not support DMA this is a usefull optimisation for building display lists. +So even with a small 8-bit controller that does not support DMA this is a usefull optimization for building display lists. Using DMA has one caveat: we need to limit the transfer to <4k as we are writing to the FIFO of EVEs command co-processor. This is usually not an issue though as we can shorten the display list generation with previously generated snippets that we attach to the current list with CMD_APPEND. And when we use widgets like CMD_BUTTON or CMD_CLOCK the generated display list grows by a larger amount than what we need to put into the command-FIFO so we likely reach the 8k limit of the display-list before we hit the 4k limit of the command-FIFO. +It is possible to use two or more DMA transfers to the FIFO to build a single display list, either to get around the 4k limit of the FIFO or in order to distribute the workload better of the time necessary between two display renewals. + +You could for example do this, spread over three consecutive calls: +```` +EVE_start_cmd_burst(); +EVE_cmd_dl_burst(CMD_DLSTART); +EVE_cmd_dl_burst(DL_CLEAR_RGB | WHITE); +EVE_end_cmd_burst(); +```` + +```` +EVE_start_cmd_burst(); +EVE_cmd_dl_burst(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG); +EVE_color_rgb_burst(BLACK); +EVE_end_cmd_burst(); +```` + +```` +EVE_start_cmd_burst(); +EVE_cmd_text_burst(5, 15, 28, 0, "Hello there!"); +EVE_cmd_dl_burst(DL_DISPLAY); +EVE_cmd_dl_burst(CMD_SWAP); +EVE_end_cmd_burst(); +```` + +But you need to check with EVE_busy() before each of these blocks. +Maybe similar like this never compiled pseudo-code: + +thread_1ms_update_display() +{ + static uint8_t state = 0; + static uint8_t count = 0; + + count++; + + if(EVE_busy() == E_OK) + { + switch(state) + { + case 0: + update_first(); + state = 1; + break; + case 1: + update_second(); + state = 2; + break; + case 2: + if(counter > 19) + { + update_last_swap_list(); + count = 0; + state = 0; + } + break; + } + } +} + ## Remarks @@ -145,19 +204,19 @@ There is a list of available options at the start of EVE_config.h sorted by chip - Provide the pins used for Chip-Select and Power-Down in EVE_target.h for the target configuration you are using -When compiling for AVR you need to provide the clock it is running at in order to make the _delay_ms() calls used to initialise the TFT work with the intended timing. +When compiling for AVR you need to provide the clock it is running at in order to make the _delay_ms() calls used to initialize the TFT work with the intended timing. For other plattforms you need to provide a DELAY_MS(ms) function that works at least between 1ms and 56ms and is not performing these delays shorter than requested. The DELAY_MS(ms) is only used during initialization of the FT8xx/BT8xx. See EVE_target.h for examples. -In Addition you need to initialise the pins used for Chip-Select and PowerDown in your hardware correctly to output. +In Addition you need to initialize the pins used for Chip-Select and Power-Down in your hardware correctly to output. Plus setup the SPI accordingly, mode-0, 8-bit, MSB-first, not more than 11MHz for the init. A couple of targets already have a function EVE_init_spi() in EVE_target.c. A word of "warning", you have to take a little care yourself to for example not send more than 4kB at once to the command co-processor or to not generate display lists that are longer than 8kB. My library does not check and re-check the command-FIFO on every step. -This is optimised for speed so the training wheels are off. +This is optimized for speed, so the training wheels are off. ## Post questions here diff --git a/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/library.json b/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/library.json index d1ace70..278b2ff 100644 --- a/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/library.json +++ b/examples/EVE_Test_SAME51_EVE3-43G/EmbeddedVideoEngine/library.json @@ -1,6 +1,6 @@ { "name": "EmbeddedVideoEngine", - "version": "5.0.3", + "version": "5.0.4", "keywords": "TFT, SPI, EVE2, EVE3, EVE4 ,Bridgetek, F81x, FT813, BT81x, BT815, BT817", "description": "Code library for EVE2/EVE3/EVE4 graphics controller ICs from FTDI/Bridgetek", "repository": { diff --git a/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/EVE_commands.c b/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/EVE_commands.c index dc36d8a..3b22ec8 100644 --- a/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/EVE_commands.c +++ b/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/EVE_commands.c @@ -2,7 +2,7 @@ @file EVE_commands.c @brief contains FT8xx / BT8xx functions @version 5.0 -@date 2021-12-27 +@date 2022-04-23 @author Rudolph Riedel @section info @@ -15,7 +15,7 @@ The c-standard is C99. MIT License -Copyright (c) 2016-2021 Rudolph Riedel +Copyright (c) 2016-2022 Rudolph Riedel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, @@ -159,6 +159,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH - finally removed EVE_cmd_start() after setting it to deprecatd with the first 5.0 release - renamed EVE_cmd_execute() to EVE_execute_cmd() to be more consistent, this is is not an EVE command - changed EVE_init_flash() to return E_OK in case of success and more meaningfull values in case of failure +- added the return-value of EVE_FIFO_HALF_EMPTY to EVE_busy() to indicate there is more than 2048 bytes available */ @@ -305,8 +306,9 @@ void EVE_memWrite_sram_buffer(uint32_t ftAddress, const uint8_t *data, uint32_t /** * @brief Check if the co-processor completed executing the current command list. * - * @return returns E_OK in case EVE is not busy (REG_CMDB_SPACE has the value 0xffc), - * returns EVE_IS_BUSY if a DMA transfer is active or REG_CMDB_SPACE has a value smaller than 0xffc + * @return returns E_OK in case EVE is not busy (no DMA transfer active and REG_CMDB_SPACE has the value 0xffc, meaning the CMD-FIFO is empty), + * returns EVE_FIFO_HALF_EMPTY if no DMA transfer is active and REG_CMDB_SPACE shows more than 2048 bytes available, + * returns EVE_IS_BUSY if a DMA transfer is active or REG_CMDB_SPACE has a value smaller than 0xffc, */ uint8_t EVE_busy(void) { @@ -357,8 +359,19 @@ uint8_t EVE_busy(void) #endif } - - return (space != 0xffc) ? EVE_IS_BUSY : E_OK; + + if(space == 0xffc) + { + return E_OK; + } + else if(space > 0x800) + { + return EVE_FIFO_HALF_EMPTY; + } + else + { + return EVE_IS_BUSY; + } } diff --git a/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/EVE_commands.h b/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/EVE_commands.h index a273f2d..a2a70fc 100644 --- a/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/EVE_commands.h +++ b/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/EVE_commands.h @@ -2,14 +2,14 @@ @file EVE_commands.h @brief contains FT8xx / BT8xx function prototypes @version 5.0 -@date 2021-12-27 +@date 2022-04-23 @author Rudolph Riedel @section LICENSE MIT License -Copyright (c) 2016-2021 Rudolph Riedel +Copyright (c) 2016-2022 Rudolph Riedel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, @@ -81,6 +81,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH - added an enum with return codes to have the functions return something more meaningfull - finally removed EVE_cmd_start() after setting it to deprecatd with the first 5.0 release - renamed EVE_cmd_execute() to EVE_execute_cmd() to be more consistent, this is is not an EVE command +- added the return-value of EVE_FIFO_HALF_EMPTY to EVE_busy() to indicate there is more than 2048 bytes available */ @@ -106,7 +107,8 @@ enum EVE_FAIL_FLASHFAST_SECTOR0_FAILED, EVE_FAIL_FLASHFAST_BLOB_MISMATCH, EVE_FAIL_FLASHFAST_SPEED_TEST, - EVE_IS_BUSY + EVE_IS_BUSY, + EVE_FIFO_HALF_EMPTY }; diff --git a/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/EVE_target.c b/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/EVE_target.c index fc3ee20..d98c64e 100644 --- a/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/EVE_target.c +++ b/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/EVE_target.c @@ -2,14 +2,14 @@ @file EVE_target.c @brief target specific functions for plain C targets @version 5.0 -@date 2021-12-04 +@date 2022-04-23 @author Rudolph Riedel @section LICENSE MIT License -Copyright (c) 2016-2021 Rudolph Riedel +Copyright (c) 2016-2022 Rudolph Riedel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, @@ -49,6 +49,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH - split up this file in EVE_target.c for the plain C targets and EVE_target.cpp for the Arduino C++ targets - converted all TABs to SPACEs - split the ATSAMC21 and ATSAMx51 targets into separate sections +- added more defines for ATSAMC21 and ATSAMx51 - chip crises... */ @@ -62,7 +63,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH /*----------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------*/ - #if defined (__SAMC21E18A__) || (__SAMC21J18A__) + #if defined (__SAMC21E18A__) || (__SAMC21J18A__) || (__SAMC21J17A__) || (__SAMC21J16A__) /* note: target as set by AtmelStudio, valid are all from the same family */ void DELAY_MS(uint16_t val) @@ -136,7 +137,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH /*----------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------*/ - #if defined (__SAME51J19A__) || (__SAMD51P20A__) || (__SAMD51J19A__) || (__SAMD51G18A__) + #if defined (__SAME51J19A__) || (__SAME51J18A__) || (__SAMD51P20A__) || (__SAMD51J19A__) || (__SAMD51G18A__) /* note: target as set by AtmelStudio, valid are all from the same family */ void DELAY_MS(uint16_t val) diff --git a/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/EVE_target.h b/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/EVE_target.h index 75ac1da..a75292a 100644 --- a/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/EVE_target.h +++ b/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/EVE_target.h @@ -2,14 +2,14 @@ @file EVE_target.h @brief target specific includes, definitions and functions @version 5.0 -@date 2021-12-27 +@date 2022-04-23 @author Rudolph Riedel @section LICENSE MIT License -Copyright (c) 2016-2021 Rudolph Riedel +Copyright (c) 2016-2022 Rudolph Riedel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, @@ -85,6 +85,8 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH - made the pin defines for all targets that have one optional - split the ATSAMC21 and ATSAMx51 targets into separate sections - updated the explanation of how DMA works +- added a TMS320F28335 target +- added more defines for ATSAMC21 and ATSAMx51 - chip crises... */ @@ -132,7 +134,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH while(val > 0) { - for(counter=0; counter < 2000;counter++) // maybe ~1ms at 16MHz clock + for(counter=0; counter < 2000;counter++) /* maybe ~1ms at 16MHz clock */ { __asm__ volatile ("nop"); } @@ -250,7 +252,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH static inline void spi_transmit(uint8_t data) { EVE_SPI.DATA = data; - while(!(EVE_SPI.STATUS & 0x80)) {}; // wait for transmit complete + while(!(EVE_SPI.STATUS & 0x80)) {}; /* wait for transmit complete */ } static inline void spi_transmit_32(uint32_t data) @@ -270,7 +272,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH static inline uint8_t spi_receive(uint8_t data) { EVE_SPI.DATA = data; - while(!(EVE_SPI.STATUS & 0x80)) {}; // wait for transmit complete + while(!(EVE_SPI.STATUS & 0x80)) {}; /* wait for transmit complete */ return EVE_SPI.DATA; } @@ -330,13 +332,13 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH SPDR = data; /* start transmission */ while(!(SPSR & (1<>= 1; @@ -378,9 +380,9 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH uint8_t spiInByte = 0; uint8_t k; - for(k = 0; k <8; k++) // Output each bit of spiOutByte + for(k = 0; k <8; k++) /* Output each bit of spiOutByte */ { - if(data & spiIndex) // Output MOSI Bit + if(data & spiIndex) /* Output MOSI Bit */ { PORTC |= (1< #if !defined (EVE_CS) #define EVE_CS_PORT 0 @@ -1088,12 +1089,12 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH static inline void EVE_cs_set(void) { - gpio_put(EVE_CS, 0); // active low + gpio_put(EVE_CS, 0); } static inline void EVE_cs_clear(void) { - gpio_put(EVE_CS, 1); // active high + gpio_put(EVE_CS, 1); } static inline void EVE_pdn_set(void) @@ -1405,13 +1406,13 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #if !defined (EVE_CS) #define RIVERDI_PORT GPIO_PORT_P1 - #define RIVERDI_SIMO BIT6 // P1.6 - #define RIVERDI_SOMI BIT7 // P1.7 - #define RIVERDI_CLK BIT5 // P1.5 + #define RIVERDI_SIMO BIT6 /* P1.6 */ + #define RIVERDI_SOMI BIT7 /* P1.7 */ + #define RIVERDI_CLK BIT5 /* P1.5 */ #define EVE_CS_PORT GPIO_PORT_P5 - #define EVE_CS GPIO_PIN0 //P5.0 + #define EVE_CS GPIO_PIN0 /* P5.0 */ #define EVE_PDN_PORT GPIO_PORT_P5 - #define EVE_PDN GPIO_PIN1 //P5.1 + #define EVE_PDN GPIO_PIN1 /* P5.1 */ #endif void EVE_SPI_Init(void); @@ -1422,7 +1423,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH while(val > 0) { - for(counter=0; counter < 8000;counter++) // ~1ms at 48MHz Core-Clock + for(counter=0; counter < 8000;counter++) /* ~1ms at 48MHz Core-Clock */ { __nop(); } @@ -1502,6 +1503,95 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #endif /* __TI_ARM */ #endif +/*----------------------------------------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------------------------------------*/ + +/* this is for TIs C2000 compiled with their ti-cgt-c2000 compiler which does not define this many symbols */ +#if defined (__TMS320C28XX__) + + /* the designated target actually is a TMS320F28335 */ + /* credit for this goes to David Sakal-Sega */ + /* note: the SPI unit of the TMS320F28335 does not support DMA, using one of the UARTs in SPI mode would allow DMA */ + + #include + #include + + typedef uint_least8_t uint8_t; /* this architecture does not actually know what a byte is, uint_least8_t is 16 bits wide */ + + /* 150MHz -> 6.67ns per cycle, 5 cycles for the loop itself and 8 NOPs -> 1ms / (6.67ns * 13) = 11532 */ + #define EVE_DELAY_1MS 12000 + + static inline void DELAY_MS(uint16_t val) + { + uint16_t counter; + + while(val > 0) + { + for(counter=0; counter < EVE_DELAY_1MS;counter++) + { + asm(" RPT #7 || NOP"); + } + val--; + } + } + + static inline void EVE_pdn_set(void) + { + GpioDataRegs.GPACLEAR.bit.GPIO14 = 1; /* Power-Down low */ + } + + static inline void EVE_pdn_clear(void) + { + GpioDataRegs.GPASET.bit.GPIO14 = 1; /* Power-Down high */ + } + + static inline void EVE_cs_set(void) + { + GpioDataRegs.GPACLEAR.bit.GPIO19 = 1; /* CS low */ + } + + static inline void EVE_cs_clear(void) + { + asm(" RPT #60 || NOP"); /* wait 60 cycles to make sure CS is not going high too early */ + GpioDataRegs.GPASET.bit.GPIO19 = 1; /* CS high */ + } + + static inline void spi_transmit(uint8_t data) + { + SpiaRegs.SPITXBUF = (data & 0xFF) << 8; /* start transfer, looks odd with data = uint8_t but uint8_t actually is 16 bits wide on this controller */ + while(SpiaRegs.SPISTS.bit.INT_FLAG == 0); /* wait for transmission to complete */ + (void) SpiaRegs.SPIRXBUF; /* dummy read to clear the flags */ + } + + static inline void spi_transmit_32(uint32_t data) + { + spi_transmit((uint8_t)(data & 0x000000ff)); + spi_transmit((uint8_t)(data >> 8)); + spi_transmit((uint8_t)(data >> 16)); + spi_transmit((uint8_t)(data >> 24)); + } + + /* spi_transmit_burst() is only used for cmd-FIFO commands so it *always* has to transfer 4 bytes */ + static inline void spi_transmit_burst(uint32_t data) + { + spi_transmit_32(data); + } + + static inline uint8_t spi_receive(uint8_t data) + { + SpiaRegs.SPITXBUF = (data & 0xFF) << 8; /* start transfer */ + while(SpiaRegs.SPISTS.bit.INT_FLAG == 0); /* wait for transmission to complete */ + return (SpiaRegs.SPIRXBUF & 0x00FF); /* data is right justified in SPIRXBUF */ + } + + static inline uint8_t fetch_flash_byte(const uint8_t *data) + { + return *data; + } + +#endif + + /*----------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------*/ diff --git a/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/README.md b/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/README.md index 5e308b4..f7305d6 100644 --- a/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/README.md +++ b/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/README.md @@ -72,7 +72,7 @@ FT810, FT811, FT812, FT813, BT815, BT816, BT817 and BT818 can use the exact same As a side effect all commands are automatically started now. Second is that there are two sets of display-list building command functions now: EVE_cmd_xxx() and EVE_cmd_xxx_burst(). -The EVE_cmd_xxx_burst() functions are optimised for speed, these are pure data transfer functions and do not even check anymore if burst mode is active. +The EVE_cmd_xxx_burst() functions are optimized for speed, these are pure data transfer functions and do not even check anymore if burst mode is active. ## Structure @@ -119,19 +119,78 @@ while (EVE_busy()); ```` This does the same as the first example but faster. -The trailing EVE_start_cmd_burst() either sets chip-select to low and sends out the three byte address. +The preceding EVE_start_cmd_burst() either sets chip-select to low and sends out the three byte address. Or if DMA is available for the target you are compiling for with support code in EVE_target.c / EVE_target.cpp and EVE_target.h, it writes the address to EVE_dma_buffer and sets EVE_dma_buffer_index to 1. Note the trailing "_burst" in the following functions, these are special versions of these commands that can only be used within an EVE_start_cmd_burst()/EVE_end_cmd_bust() pair. -These functions are optimised to push out data and nothing else. +These functions are optimized to push out data and nothing else. -The final EVE_end_cmd_bust() either pulls back the chip-select to high. +The final EVE_end_cmd_burst() either pulls back the chip-select to high. Or if we have DMA it calls EVE_start_dma_transfer() to start pushing out the buffer in the background. As we have 7 commands for EVE in these simple examples, the second one has the address overhead removed from six commands and therefore needs to transfer 18 bytes less over SPI. -So even with a small 8-bit controller that does not support DMA this is a usefull optimisation for building display lists. +So even with a small 8-bit controller that does not support DMA this is a usefull optimization for building display lists. Using DMA has one caveat: we need to limit the transfer to <4k as we are writing to the FIFO of EVEs command co-processor. This is usually not an issue though as we can shorten the display list generation with previously generated snippets that we attach to the current list with CMD_APPEND. And when we use widgets like CMD_BUTTON or CMD_CLOCK the generated display list grows by a larger amount than what we need to put into the command-FIFO so we likely reach the 8k limit of the display-list before we hit the 4k limit of the command-FIFO. +It is possible to use two or more DMA transfers to the FIFO to build a single display list, either to get around the 4k limit of the FIFO or in order to distribute the workload better of the time necessary between two display renewals. + +You could for example do this, spread over three consecutive calls: +```` +EVE_start_cmd_burst(); +EVE_cmd_dl_burst(CMD_DLSTART); +EVE_cmd_dl_burst(DL_CLEAR_RGB | WHITE); +EVE_end_cmd_burst(); +```` + +```` +EVE_start_cmd_burst(); +EVE_cmd_dl_burst(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG); +EVE_color_rgb_burst(BLACK); +EVE_end_cmd_burst(); +```` + +```` +EVE_start_cmd_burst(); +EVE_cmd_text_burst(5, 15, 28, 0, "Hello there!"); +EVE_cmd_dl_burst(DL_DISPLAY); +EVE_cmd_dl_burst(CMD_SWAP); +EVE_end_cmd_burst(); +```` + +But you need to check with EVE_busy() before each of these blocks. +Maybe similar like this never compiled pseudo-code: + +thread_1ms_update_display() +{ + static uint8_t state = 0; + static uint8_t count = 0; + + count++; + + if(EVE_busy() == E_OK) + { + switch(state) + { + case 0: + update_first(); + state = 1; + break; + case 1: + update_second(); + state = 2; + break; + case 2: + if(counter > 19) + { + update_last_swap_list(); + count = 0; + state = 0; + } + break; + } + } +} + ## Remarks @@ -145,19 +204,19 @@ There is a list of available options at the start of EVE_config.h sorted by chip - Provide the pins used for Chip-Select and Power-Down in EVE_target.h for the target configuration you are using -When compiling for AVR you need to provide the clock it is running at in order to make the _delay_ms() calls used to initialise the TFT work with the intended timing. +When compiling for AVR you need to provide the clock it is running at in order to make the _delay_ms() calls used to initialize the TFT work with the intended timing. For other plattforms you need to provide a DELAY_MS(ms) function that works at least between 1ms and 56ms and is not performing these delays shorter than requested. The DELAY_MS(ms) is only used during initialization of the FT8xx/BT8xx. See EVE_target.h for examples. -In Addition you need to initialise the pins used for Chip-Select and PowerDown in your hardware correctly to output. +In Addition you need to initialize the pins used for Chip-Select and Power-Down in your hardware correctly to output. Plus setup the SPI accordingly, mode-0, 8-bit, MSB-first, not more than 11MHz for the init. A couple of targets already have a function EVE_init_spi() in EVE_target.c. A word of "warning", you have to take a little care yourself to for example not send more than 4kB at once to the command co-processor or to not generate display lists that are longer than 8kB. My library does not check and re-check the command-FIFO on every step. -This is optimised for speed so the training wheels are off. +This is optimized for speed, so the training wheels are off. ## Post questions here diff --git a/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/library.json b/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/library.json index d1ace70..278b2ff 100644 --- a/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/library.json +++ b/examples/EVE_Test_XMEGA128A1_GEN4-FT813-50CTP/Display_Test1/EmbeddedVideoEngine/library.json @@ -1,6 +1,6 @@ { "name": "EmbeddedVideoEngine", - "version": "5.0.3", + "version": "5.0.4", "keywords": "TFT, SPI, EVE2, EVE3, EVE4 ,Bridgetek, F81x, FT813, BT81x, BT815, BT817", "description": "Code library for EVE2/EVE3/EVE4 graphics controller ICs from FTDI/Bridgetek", "repository": { diff --git a/library.json b/library.json index d1ace70..278b2ff 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "EmbeddedVideoEngine", - "version": "5.0.3", + "version": "5.0.4", "keywords": "TFT, SPI, EVE2, EVE3, EVE4 ,Bridgetek, F81x, FT813, BT81x, BT815, BT817", "description": "Code library for EVE2/EVE3/EVE4 graphics controller ICs from FTDI/Bridgetek", "repository": {