image/svg+xml
Brteve's API for EveApps
Version 0.0.1
The reference document for common folder of EveApps project.
 
Loading...
Searching...
No Matches
EVE_HalImpl_RP2040.c
Go to the documentation of this file.
1
32#include "EVE_HalImpl.h"
33#include "EVE_Platform.h"
34#if defined(RP2040_PLATFORM)
35
36/*********
37** INIT **
38*********/
39
40static int s_SpiOpened[2];
41
42bool EVE_Hal_NoInit = false;
43
46
52{
53 /* no-op */
54}
55
61{
62 eve_assert(!s_SpiOpened[0]);
63 eve_assert(!s_SpiOpened[1]);
64}
65
71{
72 /* List two SPI channels, but they may be used multiple times with different CS/PWD pin selection */
73 return 2;
74}
75
82EVE_HAL_EXPORT void EVE_Hal_info(EVE_DeviceInfo *deviceInfo, size_t deviceIdx)
83{
84 memset(deviceInfo, 0, sizeof(EVE_DeviceInfo));
85 strcpy_s(deviceInfo->DisplayName, sizeof(deviceInfo->DisplayName), deviceIdx ? "RP2040 SPI1" : "RP2040 SPI0");
86 strcpy_s(deviceInfo->SerialNumber, sizeof(deviceInfo->SerialNumber), deviceIdx ? "RP2040 SPI1" : "RP2040 SPI0");
87 deviceInfo->Opened = s_SpiOpened[deviceIdx];
88 deviceInfo->Host = EVE_HOST_EMBEDDED;
89}
90
99EVE_HAL_EXPORT bool EVE_Hal_isDevice(EVE_HalContext *phost, size_t deviceIdx)
100{
101 return deviceIdx ? (phost->SpiPort == spi1) : (phost->SpiPort == spi0);
102}
103
112bool EVE_HalImpl_defaults(EVE_HalParameters *parameters, size_t deviceIdx)
113{
114 if (deviceIdx != 0 && deviceIdx != 1)
115 {
116 /* Alternate between SPI0 and SPI1 when opening */
117#if EVE_DEFAULT_SPI0_ONLY
118 deviceIdx = 0;
119#else
120 deviceIdx = (s_SpiOpened[1] < s_SpiOpened[0]) ? 1 : 0;
121#endif
122 }
123 parameters->DeviceIdx = deviceIdx;
124 parameters->PowerDownPin = deviceIdx ? EVE_DEFAULT_SPI1_PWD : EVE_DEFAULT_SPI0_PWD;
125 /* Calculate CS down from SPI1 CS2 if multiple devices are opened on one SPI port */
126 parameters->SpiCsPin = (!s_SpiOpened[deviceIdx])
127 ? (deviceIdx ? EVE_DEFAULT_SPI1_CS1 : EVE_DEFAULT_SPI0_CS)
128 : (EVE_DEFAULT_SPI1_CS2 - (s_SpiOpened[0] + s_SpiOpened[1]));
129 parameters->SpiSckPin = deviceIdx ? EVE_DEFAULT_SPI1_SCK : EVE_DEFAULT_SPI0_SCK;
130 parameters->SpiMosiPin = deviceIdx ? EVE_DEFAULT_SPI1_MOSI : EVE_DEFAULT_SPI0_MOSI;
131 parameters->SpiMisoPin = deviceIdx ? EVE_DEFAULT_SPI1_MISO : EVE_DEFAULT_SPI0_MISO;
132 return true;
133}
134
142void setSPI(EVE_HalContext *phost, EVE_SPI_CHANNELS_T numchnls, uint8_t numdummy)
143{
144 /* SPI initialisation. This will use SPI at 1MHz */
145 size_t deviceIdx = phost->SpiPort == spi1 ? 1 : 0;
146 spi_init(phost->SpiPort, 1000 * 1000);
147 gpio_set_function(phost->SpiMisoPin, GPIO_FUNC_SPI);
148 gpio_set_function(phost->SpiMosiPin, GPIO_FUNC_SPI);
149 gpio_set_function(phost->SpiSckPin, GPIO_FUNC_SPI);
150
151 /* Chip select is active-low, so we'll initialise it to a driven-high state */
152 gpio_init(phost->SpiCsPin);
153 gpio_set_dir(phost->SpiCsPin, GPIO_OUT);
154 gpio_put(phost->SpiCsPin, 1);
155
156 /* Only support single channel */
158 phost->SpiDummyBytes = 1;
159}
160
169bool EVE_HalImpl_open(EVE_HalContext *phost, const EVE_HalParameters *parameters)
170{
171 phost->SpiPort = parameters->DeviceIdx ? spi1 : spi0;
172 phost->SpiCsPin = parameters->SpiCsPin;
173 phost->SpiSckPin = parameters->SpiSckPin;
174 phost->SpiMosiPin = parameters->SpiMosiPin;
175 phost->SpiMisoPin = parameters->SpiMisoPin;
176 phost->PowerDownPin = parameters->PowerDownPin;
177
178 eve_printf_debug("Open port %s for EVE\n", parameters->DeviceIdx ? "SPI1" : "SPI0");
179 eve_printf_debug("CS: GP%i, SCK: GP%i, MOSI: GP%i, MISO: GP%i, PWD: GP%i\n",
180 (int)phost->SpiCsPin, (int)phost->SpiSckPin, (int)phost->SpiMosiPin,
181 (int)phost->SpiMisoPin, (int)phost->PowerDownPin);
182
183#ifdef EVE_MULTI_GRAPHICS_TARGET
184 phost->GpuDefs = &EVE_GpuDefs_FT80X;
185#endif
186
187 gpio_init(phost->PowerDownPin);
188 gpio_set_dir(phost->PowerDownPin, GPIO_OUT);
189 gpio_put(phost->PowerDownPin, 0);
190
191 /* Initialize single channel */
193
194 gpio_put(phost->PowerDownPin, 1);
195
196 /* Initialize the context variables */
197 phost->Status = EVE_STATUS_OPENED;
199 ++s_SpiOpened[parameters->DeviceIdx];
200
201 return true;
202}
203
210{
211 size_t deviceIdx = phost->SpiPort == spi1 ? 1 : 0;
212 phost->Status = EVE_STATUS_CLOSED;
213 --s_SpiOpened[deviceIdx];
215 if (!s_SpiOpened[deviceIdx])
216 {
217 spi_deinit(phost->SpiPort);
218 }
219}
220
227{
228 /* no-op */
229}
231
232/*************
233** TRANSFER **
234*************/
235
238
239static inline void csSelect(EVE_HalContext *phost)
240{
241 asm volatile("nop \n nop \n nop");
242 gpio_put(phost->SpiCsPin, 0); /* Active low */
243 asm volatile("nop \n nop \n nop");
244}
245
246static inline void csDeselect(EVE_HalContext *phost)
247{
248 asm volatile("nop \n nop \n nop");
249 gpio_put(phost->SpiCsPin, 1);
250 asm volatile("nop \n nop \n nop");
251}
252
253// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
254
263{
265
266 if (rw == EVE_TRANSFER_READ)
267 {
268 eve_assert(3 + phost->SpiDummyBytes <= 5);
269 uint8_t spidata[5];
270 spidata[0] = (addr >> 16);
271 spidata[1] = (addr >> 8);
272 spidata[2] = addr & 0xff;
273 csSelect(phost);
274 spi_write_blocking(phost->SpiPort, spidata, 3 + phost->SpiDummyBytes);
275 phost->Status = EVE_STATUS_READING;
276 }
277 else
278 {
279 uint8_t spidata[4];
280 spidata[0] = (0x80 | (addr >> 16));
281 spidata[1] = (addr >> 8);
282 spidata[2] = addr;
283
284 csSelect(phost);
285 spi_write_blocking(phost->SpiPort, spidata, 3);
286
287 phost->Status = EVE_STATUS_WRITING;
288 }
289}
290
297{
299
300 csDeselect(phost);
301 phost->Status = EVE_STATUS_OPENED;
302}
303
309void EVE_Hal_flush(EVE_HalContext *phost)
310{
312 /* no-op */
313}
314
322static inline void rdBuffer(EVE_HalContext *phost, uint8_t *buffer, uint32_t size)
323{
324 spi_read_blocking(phost->SpiPort, 0, buffer, size);
325}
326
334static inline void wrBuffer(EVE_HalContext *phost, const uint8_t *buffer, uint32_t size)
335{
336 spi_write_blocking(phost->SpiPort, buffer, size);
337}
338
346static inline uint8_t transfer8(EVE_HalContext *phost, uint8_t value)
347{
348 if (phost->Status == EVE_STATUS_READING)
349 {
350 rdBuffer(phost, &value, 1);
351 return value;
352 }
353 else
354 {
355 wrBuffer(phost, &value, 1);
356 return 0;
357 }
358}
359
368{
369 return transfer8(phost, value);
370}
371
380{
381 uint8_t buffer[2];
382 if (phost->Status == EVE_STATUS_READING)
383 {
384 rdBuffer(phost, buffer, 2);
385 return (uint16_t)buffer[0]
386 | (uint16_t)buffer[1] << 8;
387 }
388 else
389 {
390 buffer[0] = value & 0xFF;
391 buffer[1] = value >> 8;
392 wrBuffer(phost, buffer, 2);
393 return 0;
394 }
395}
396
405{
406 uint8_t buffer[4];
407 if (phost->Status == EVE_STATUS_READING)
408 {
409 rdBuffer(phost, buffer, 4);
410 return (uint32_t)buffer[0]
411 | (uint32_t)buffer[1] << 8
412 | (uint32_t)buffer[2] << 16
413 | (uint32_t)buffer[3] << 24;
414 }
415 else
416 {
417 buffer[0] = value & 0xFF;
418 buffer[1] = (value >> 8) & 0xFF;
419 buffer[2] = (value >> 16) & 0xFF;
420 buffer[3] = value >> 24;
421 wrBuffer(phost, buffer, 4);
422 return 0;
423 }
424}
425
434void EVE_Hal_transferMem(EVE_HalContext *phost, uint8_t *result, const uint8_t *buffer, uint32_t size)
435{
436 if (!size)
437 return;
438
439 if (result && buffer)
440 {
441 /* not implemented */
443 }
444 else if (result)
445 {
446 rdBuffer(phost, result, size);
447 }
448 else if (buffer)
449 {
450 wrBuffer(phost, buffer, size);
451 }
452}
453
463{
464 if (!size)
465 return;
466
467 if (result && buffer)
468 {
469 /* not implemented */
471 }
472 else if (result)
473 {
474 /* not implemented */
476 }
477 else if (buffer)
478 {
479 wrBuffer(phost, buffer, size);
480 }
481}
482
493uint32_t EVE_Hal_transferString(EVE_HalContext *phost, const char *str, uint32_t index, uint32_t size, uint32_t padMask)
494{
495 if (!size)
496 {
497 /* TODO: Support different padding options */
498 eve_assert(padMask == 0x3);
499 EVE_Hal_transfer32(phost, 0);
500 return 4;
501 }
502
504 uint32_t transferred = 0;
505 if (phost->Status == EVE_STATUS_WRITING)
506 {
507 transferred += (uint32_t)strnlen(str, size) + 1;
508 eve_assert(str[transferred - 1] == '\0');
509 wrBuffer(phost, (uint8_t *)str, transferred);
510 if (transferred & padMask)
511 {
512 uint32_t pad = 4 - (transferred & padMask);
513 uint8_t padding[4] = { 0 };
514 wrBuffer(phost, padding, pad);
515 transferred += pad;
516 eve_assert(!(transferred & 0x3));
517 }
518 }
519 else
520 {
521 /* not implemented */
523 }
524 return transferred;
525}
527
528/************
529** UTILITY **
530************/
531
534
542{
544
545 uint8_t hcmd[4] = { 0 };
546 hcmd[0] = cmd;
547 hcmd[1] = 0;
548 hcmd[2] = 0;
549 hcmd[3] = 0;
550
551 csSelect(phost);
552 spi_write_blocking(phost->SpiPort, hcmd, 3);
553 csDeselect(phost);
554}
555
563{
565
566 uint8_t hcmd[4] = { 0 };
567 hcmd[0] = cmd & 0xff;
568 hcmd[1] = (cmd >> 8) & 0xff;
569 hcmd[2] = (cmd >> 16) & 0xff;
570 hcmd[3] = 0;
571
572 csSelect(phost);
573 spi_write_blocking(phost->SpiPort, hcmd, 3);
574 csDeselect(phost);
575}
576
585bool EVE_Hal_powerCycle(EVE_HalContext *phost, bool up)
586{
587 if (up)
588 {
589 /* Power down */
590 gpio_put(phost->PowerDownPin, 0);
591 EVE_sleep(20);
592
593 /* Reset the core, in case PD pin is not wired */
596 EVE_sleep(20);
597
598 /* Power up */
599 gpio_put(phost->PowerDownPin, 1);
600 EVE_sleep(20);
601 }
602 else
603 {
604 /* Power down */
605 gpio_put(phost->PowerDownPin, 0);
606 EVE_sleep(20);
607
608 /* Reset the core, in case PD pin is not wired */
611 }
612 return true;
613}
614
622void EVE_Hal_setSPI(EVE_HalContext *phost, EVE_SPI_CHANNELS_T numchnls, uint8_t numdummy)
623{
624 if (EVE_CHIPID < EVE_FT810)
625 return;
626
627 uint8_t writebyte = 0;
628
629 if ((numchnls > EVE_SPI_QUAD_CHANNEL) || (numdummy > 2) || (numdummy < 1))
630 return; // error
631
632 // Switch EVE to multi channel SPI mode
633 writebyte = numchnls;
634 if (numdummy == 2)
635 writebyte |= EVE_SPI_TWO_DUMMY_BYTES;
636 EVE_Hal_wr8(phost, REG_SPI_WIDTH, writebyte);
637 EVE_Hal_flush(phost);
638
639 // Switch RP2040 to multi channel SPI mode
640 setSPI(phost, numchnls, numdummy);
641}
642
644{
645 if (EVE_CHIPID < EVE_FT810)
646 return;
647
648 setSPI(phost, phost->SpiChannels, phost->SpiDummyBytes);
649}
650
658{
659 return 0; /* TODO */
660}
662
663/*********
664** MISC **
665*********/
666
669
675{
676 if (!EVE_Hal_NoInit)
677 {
678 stdio_init_all();
679 }
680
681 eve_printf_debug("--------------------------------\n");
682 eve_printf_debug("- Bridgetek EVE HAL for RP2040 -\n");
683 eve_printf_debug("--------------------------------\n");
684}
685
690void EVE_Mcu_release()
691{
692 /* no-op */
693}
695
696/*********
697** MISC **
698*********/
699
700/* Globals for interrupt implementation */
701static absolute_time_t s_LastTime;
703static int32_t s_RemainderMicros;
704
707
712{
713 s_LastTime = get_absolute_time();
715 s_RemainderMicros = 0;
716}
717
723{
724 /* no-op */
725}
726
727static inline void updateMillis()
728{
729 absolute_time_t newTime = get_absolute_time();
730 int64_t diff = absolute_time_diff_us(s_LastTime, newTime);
731 diff += s_RemainderMicros;
732 if (diff >= 1000)
733 {
735 diff -= 1000;
736 if (diff >= 1000)
737 {
738 uint64_t ms = diff / 1000;
740 diff -= (ms * 1000);
741 }
742 s_LastTime = newTime;
743 eve_assert(diff >= 0);
744 s_RemainderMicros = (int32_t)diff;
745 }
746}
747
754{
755 updateMillis();
757}
758
765{
766 updateMillis();
768}
769
775void EVE_sleep(uint32_t ms)
776{
777 sleep_ms(ms);
778}
779
780/*********
781** MISC **
782*********/
783
792{
793 return true;
794}
796
797#endif /* #if defined(RP2040_PLATFORM) */
798
799/* end of file */
static uint32_t wrBuffer(EVE_HalContext *phost, const void *buffer, uint32_t size, bool progmem, bool string)
Write buffer to Coprocessor's comand fifo.
Definition EVE_Cmd.c:191
#define EVE_CMD_STRING_MAX
Definition EVE_Cmd.h:44
#define strcpy_s(dst, sz, src)
#define EVE_HAL_EXPORT
#define EVE_CHIPID
#define eve_progmem_const
#define EVE_FT810
Definition EVE_Config.h:58
#define REG_SPI_WIDTH
@ EVE_SPI_TWO_DUMMY_BYTES
#define EVE_CORE_RESET
EVE_SPI_CHANNELS_T
@ EVE_SPI_QUAD_CHANNEL
@ EVE_SPI_SINGLE_CHANNEL
EVE_HalPlatform g_HalPlatform
Definition EVE_Hal.c:43
EVE_HAL_EXPORT void EVE_Hal_wr8(EVE_HalContext *phost, uint32_t addr, uint8_t v)
Write 8 bits to Coprocessor's memory.
Definition EVE_Hal.c:220
EVE_HAL_EXPORT bool EVE_Hal_powerCycle(EVE_HalContext *phost, bool up)
Toggle PD_N pin of FT800 board for a power cycle.
@ EVE_STATUS_READING
Definition EVE_HalDefs.h:59
@ EVE_STATUS_CLOSED
Definition EVE_HalDefs.h:57
@ EVE_STATUS_OPENED
Definition EVE_HalDefs.h:58
@ EVE_STATUS_WRITING
Definition EVE_HalDefs.h:60
EVE_HAL_EXPORT uint64_t EVE_millis64()
Get clock in miliseond.
EVE_HAL_EXPORT uint8_t EVE_Hal_transfer8(EVE_HalContext *phost, uint8_t value)
Write 8 bits to Coprocessor.
EVE_HAL_EXPORT uint16_t EVE_Hal_transfer16(EVE_HalContext *phost, uint16_t value)
Write 2 bytes to Coprocessor.
EVE_HAL_EXPORT bool EVE_Hal_isDevice(EVE_HalContext *phost, size_t deviceIdx)
Check whether the context is the specified device.
EVE_HAL_EXPORT void EVE_Hal_info(EVE_DeviceInfo *deviceInfo, size_t deviceIdx)
Get info of the specified device. Devices of type EVE_HOST_UNKNOWN should be ignored.
EVE_HAL_EXPORT uint32_t EVE_millis()
Get clock in miliseond.
EVE_HAL_EXPORT void EVE_Hal_startTransfer(EVE_HalContext *phost, EVE_TRANSFER_T rw, uint32_t addr)
Start data transfer to Coprocessor.
EVE_HAL_EXPORT void EVE_Hal_hostCommand(EVE_HalContext *phost, uint8_t cmd)
Send a host command to Coprocessor.
EVE_TRANSFER_T
Definition EVE_HalDefs.h:65
@ EVE_TRANSFER_READ
Definition EVE_HalDefs.h:67
EVE_HAL_EXPORT void EVE_Hal_setSPI(EVE_HalContext *phost, EVE_SPI_CHANNELS_T numchnls, uint8_t numdummy)
Set number of SPI channel.
EVE_HAL_EXPORT uint32_t EVE_Hal_transferString(EVE_HalContext *phost, const char *str, uint32_t index, uint32_t size, uint32_t padMask)
Transfer a string to EVE platform.
@ EVE_HOST_EMBEDDED
EVE_HAL_EXPORT size_t EVE_Hal_list()
List the available devices.
EVE_HAL_EXPORT void EVE_Hal_transferMem(EVE_HalContext *phost, uint8_t *result, const uint8_t *buffer, uint32_t size)
Transfer (read/write) a block data to Coprocessor.
EVE_HAL_EXPORT void EVE_sleep(uint32_t ms)
Sleep in milisecond.
EVE_HAL_EXPORT void EVE_Hal_transferProgMem(EVE_HalContext *phost, uint8_t *result, eve_progmem_const uint8_t *buffer, uint32_t size)
Transfer a block data from program memory.
EVE_HAL_EXPORT void EVE_Hal_restoreSPI(EVE_HalContext *phost)
EVE_HAL_EXPORT void EVE_Hal_endTransfer(EVE_HalContext *phost)
End data transfer.
EVE_HAL_EXPORT uint32_t EVE_Hal_currentFrequency(EVE_HalContext *phost)
Get current system clock of Coprocessor.
EVE_HAL_EXPORT void EVE_Hal_flush(EVE_HalContext *phost)
Flush data to Coprocessor.
EVE_HAL_EXPORT void EVE_Hal_hostCommandExt3(EVE_HalContext *phost, uint32_t cmd)
This API sends a 3byte command to the phost.
EVE_HAL_EXPORT uint32_t EVE_Hal_transfer32(EVE_HalContext *phost, uint32_t value)
Write 4 bytes to Coprocessor.
Eve_Hal framework APIs.
bool EVE_HalImpl_open(EVE_HalContext *phost, const EVE_HalParameters *parameters)
Opens a new HAL context using the specified parameters.
void EVE_Mcu_initialize()
Init FT9x host MCU.
bool EVE_HalImpl_defaults(EVE_HalParameters *parameters, size_t deviceIdx)
Get the default configuration parameters.
void EVE_Millis_release()
Release FT9x timer.
void EVE_HalImpl_close(EVE_HalContext *phost)
Close a HAL context.
void EVE_Mcu_release()
Release FT9x host MCU.
void EVE_HalImpl_initialize()
Initialize HAL platform.
void EVE_Millis_initialize()
Init FT9x timer.
bool EVE_UtilImpl_bootupDisplayGpio(EVE_HalContext *phost)
Display GPIO pins.
void EVE_HalImpl_idle(EVE_HalContext *phost)
Idle. Call regularly to update frequently changing internal state.
void EVE_HalImpl_release()
Release HAL platform.
static uint64_t s_TotalMilliseconds64
static uint8_t transfer8(EVE_HalContext *phost, uint8_t value)
Write 8 bit to Coprocessor.
void setSPI(EVE_HalContext *phost, EVE_SPI_CHANNELS_T numchnls, uint8_t numdummy)
Set number of SPI channel.
static void rdBuffer(EVE_HalContext *phost, uint8_t *buffer, uint32_t size)
Read a block data from Coprocessor.
unsigned short uint16_t
int int32_t
unsigned int uint32_t
long long int64_t
unsigned long long uint64_t
unsigned char uint8_t
Platform selector.
#define eve_assert(cond)
#define eve_printf_debug(fmt,...)
#define eve_debug_break()
static ft_uint32_t ft_uint8_t * buffer
Definition FT_Gpu_Hal.h:139
static ft_void_t ft_uint32_t * cmd
Definition FT_Gpu_Hal.h:184
static ft_uint32_t addr
Definition FT_Gpu_Hal.h:139
char DisplayName[256]
char SerialNumber[16]
EVE_HOST_T Host
uint8_t PowerDownPin
EVE_SPI_CHANNELS_T SpiChannels
EVE_STATUS_T Status
uint8_t SpiDummyBytes
uint32_t OpenedDevices