diff --git a/RTL00_SDKV35a/component/common/example/mcast/example_mcast.c b/RTL00_SDKV35a/component/common/example/mcast/example_mcast.c new file mode 100644 index 0000000..b18dae8 --- /dev/null +++ b/RTL00_SDKV35a/component/common/example/mcast/example_mcast.c @@ -0,0 +1,98 @@ +#include "FreeRTOS.h" +#include "task.h" +#include + +#include +#include +#include +extern struct netif xnetif[]; + +static void example_mcast_thread(void *param) +{ +#if LWIP_IGMP + int err = 0; + int socket = -1; + char *group_ip = "224.0.0.251"; + uint16_t port = 5353; + + // Set NETIF_FLAG_IGMP flag for netif which should process IGMP messages + xnetif[0].flags |= NETIF_FLAG_IGMP; + + if((socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + printf("ERROR: socket - AF_INET, SOCK_DGRAM\n"); + err = -1; + } + + // Add multicast group membership on this interface + if(err == 0) { + struct ip_mreq imr; + imr.imr_multiaddr.s_addr = inet_addr(group_ip); + imr.imr_interface.s_addr = INADDR_ANY; + err = setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(imr)); + if(err < 0) printf("ERROR: setsockopt - IP_ADD_MEMBERSHIP\n"); + } + + // Specify outgoing interface too + if(err == 0) { + struct in_addr intfAddr; + intfAddr.s_addr = INADDR_ANY; + err = setsockopt(socket, IPPROTO_IP, IP_MULTICAST_IF, &intfAddr, sizeof(struct in_addr)); + if(err < 0) printf("ERROR: setsockopt - IP_MULTICAST_IF\n"); + } + + // And start listening for packets + if(err == 0) { + struct sockaddr_in bindAddr; + bindAddr.sin_family = AF_INET; + bindAddr.sin_port = htons(port); + bindAddr.sin_addr.s_addr = INADDR_ANY; + err = bind(socket, (struct sockaddr *) &bindAddr, sizeof(bindAddr)); + if(err < 0) printf("ERROR: bind\n"); + } + + if(err == 0) { + unsigned char packet[1024]; + + while(1) { + // Receive multicast + int packetLen; + struct sockaddr from; + struct sockaddr_in *from_sin = (struct sockaddr_in*) &from; + socklen_t fromLen = sizeof(from); + + if((packetLen = recvfrom(socket, &packet, sizeof(packet), 0, &from, &fromLen)) >= 0) { + uint8_t *ip = (uint8_t *) &from_sin->sin_addr.s_addr; + uint16_t from_port = ntohs(from_sin->sin_port); + printf("recvfrom - %d bytes from %d.%d.%d.%d:%d\n", packetLen, ip[0], ip[1], ip[2], ip[3], from_port); + } + + // Send multicast + if(packetLen > 0) { + int sendLen; + struct sockaddr to; + struct sockaddr_in *to_sin = (struct sockaddr_in*) &to; + to_sin->sin_family = AF_INET; + to_sin->sin_port = htons(port); + to_sin->sin_addr.s_addr = inet_addr(group_ip); + + if((sendLen = sendto(socket, packet, packetLen, 0, &to, sizeof(struct sockaddr))) < 0) + printf("ERROR: sendto %s\n", group_ip); + else + printf("sendto - %d bytes to %s:%d\n", sendLen, group_ip, port); + } + } + } + else if(socket != -1) { + close(socket); + } +#else + printf("\nSHOULD ENABLE LWIP_IGMP\n"); +#endif + vTaskDelete(NULL); +} + +void example_mcast(void) +{ + if(xTaskCreate(example_mcast_thread, ((const char*)"example_mcast_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) + printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__); +} diff --git a/RTL00_SDKV35a/component/common/example/mcast/example_mcast.h b/RTL00_SDKV35a/component/common/example/mcast/example_mcast.h new file mode 100644 index 0000000..7be6823 --- /dev/null +++ b/RTL00_SDKV35a/component/common/example/mcast/example_mcast.h @@ -0,0 +1,6 @@ +#ifndef EXAMPLE_MCAST_H +#define EXAMPLE_MCAST_H + +void example_mcast(void); + +#endif /* EXAMPLE_MCAST_H */ diff --git a/RTL00_SDKV35a/component/common/example/mcast/readme.txt b/RTL00_SDKV35a/component/common/example/mcast/readme.txt new file mode 100644 index 0000000..1a6409d --- /dev/null +++ b/RTL00_SDKV35a/component/common/example/mcast/readme.txt @@ -0,0 +1,17 @@ +LWIP MULTICAST EXAMPLE + +Description: +Join multicast group of 224.0.0.251 and listen on port 5353. +Send packet with the content of received packet to multicast group of 224.0.0.251. + +Configuration: +[lwipopts.h] + #define LWIP_UDP 1 + #define LWIP_IGMP 1 +[platform_opts.h] + #define CONFIG_EXAMPLE_MCAST 1 + +Execution: +Can make automatical Wi-Fi connection when booting by using wlan fast connect example. +A multicast example thread will be started automatically when booting. + diff --git a/RTL00_SDKV35a/component/common/example/ssl_download/example_ssl_download.c b/RTL00_SDKV35a/component/common/example/ssl_download/example_ssl_download.c new file mode 100644 index 0000000..746d12a --- /dev/null +++ b/RTL00_SDKV35a/component/common/example/ssl_download/example_ssl_download.c @@ -0,0 +1,137 @@ +#include +#include +#include + +#include +#include +#include +#include + +#define SERVER_HOST "192.168.13.27" +#define SERVER_PORT 443 +#define RESOURCE "/dummy100k.bin" + +static unsigned int arc4random(void) +{ + unsigned int res = xTaskGetTickCount(); + static unsigned int seed = 0xDEADB00B; + + seed = ((seed & 0x007F00FF) << 7) ^ + ((seed & 0x0F80FF00) >> 8) ^ // be sure to stir those low bits + (res << 13) ^ (res >> 9); // using the clock too! + + return seed; +} + +static void get_random_bytes(void *buf, size_t len) +{ + unsigned int ranbuf; + unsigned int *lp; + int i, count; + count = len / sizeof(unsigned int); + lp = (unsigned int *) buf; + + for(i = 0; i < count; i ++) { + lp[i] = arc4random(); + len -= sizeof(unsigned int); + } + + if(len > 0) { + ranbuf = arc4random(); + memcpy(&lp[i], &ranbuf, len); + } +} + +static int my_random(void *p_rng, unsigned char *output, size_t output_len) +{ + get_random_bytes(output, output_len); + return 0; +} + +static void example_ssl_download_thread(void *param) +{ + int server_fd = -1, ret; + struct sockaddr_in server_addr; + ssl_context ssl; + + // Delay to wait for IP by DHCP + vTaskDelay(10000); + printf("\nExample: SSL download\n"); + + memory_set_own(pvPortMalloc, vPortFree); + memset(&ssl, 0, sizeof(ssl_context)); + + if((ret = net_connect(&server_fd, SERVER_HOST, SERVER_PORT)) != 0) { + printf("ERROR: net_connect ret(%d)\n", ret); + goto exit; + } + + if((ret = ssl_init(&ssl)) != 0) { + printf("ERRPR: ssl_init ret(%d)\n", ret); + goto exit; + } + + ssl_set_endpoint(&ssl, SSL_IS_CLIENT); + ssl_set_authmode(&ssl, SSL_VERIFY_NONE); + ssl_set_rng(&ssl, my_random, NULL); + ssl_set_bio(&ssl, net_recv, &server_fd, net_send, &server_fd); + + if((ret = ssl_handshake(&ssl)) != 0) { + printf("ERROR: ssl_handshake ret(-0x%x)", -ret); + goto exit; + } + else { + unsigned char buf[2048]; + int read_size = 0, resource_size = 0, content_len = 0, header_removed = 0; + + printf("SSL ciphersuite %s\n", ssl_get_ciphersuite(&ssl)); + sprintf(buf, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", RESOURCE, SERVER_HOST); + ssl_write(&ssl, buf, strlen(buf)); + + while((read_size = ssl_read(&ssl, buf, sizeof(buf))) > 0) { + if(header_removed == 0) { + char *header = strstr(buf, "\r\n\r\n"); + + if(header) { + char *body, *content_len_pos; + + body = header + strlen("\r\n\r\n"); + *(body - 2) = 0; + header_removed = 1; + printf("\nHTTP Header: %s\n", buf); + read_size = read_size - ((unsigned char *) body - buf); + + content_len_pos = strstr(buf, "Content-Length: "); + if(content_len_pos) { + content_len_pos += strlen("Content-Length: "); + *(strstr(content_len_pos, "\r\n")) = 0; + content_len = atoi(content_len_pos); + } + } + else { + printf("ERROR: HTTP header\n"); + goto exit; + } + } + + printf("read resource %d bytes\n", read_size); + resource_size += read_size; + } + + printf("final read size = %d bytes\n", read_size); + printf("http content-length = %d bytes, download resource size = %d bytes\n", content_len, resource_size); + } + +exit: + if(server_fd != -1) + net_close(server_fd); + + ssl_free(&ssl); + vTaskDelete(NULL); +} + +void example_ssl_download(void) +{ + if(xTaskCreate(example_ssl_download_thread, ((const char*)"example_ssl_download_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) + printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__); +} diff --git a/RTL00_SDKV35a/component/common/example/ssl_download/example_ssl_download.h b/RTL00_SDKV35a/component/common/example/ssl_download/example_ssl_download.h new file mode 100644 index 0000000..d7748ac --- /dev/null +++ b/RTL00_SDKV35a/component/common/example/ssl_download/example_ssl_download.h @@ -0,0 +1,6 @@ +#ifndef EXAMPLE_SSL_DOWNLOAD_H +#define EXAMPLE_SSL_DOWNLOAD_H + +void example_ssl_download(void); + +#endif /* EXAMPLE_SSL_DOWNLOAD_H */ diff --git a/RTL00_SDKV35a/component/common/example/ssl_download/readme.txt b/RTL00_SDKV35a/component/common/example/ssl_download/readme.txt new file mode 100644 index 0000000..e82c5b2 --- /dev/null +++ b/RTL00_SDKV35a/component/common/example/ssl_download/readme.txt @@ -0,0 +1,16 @@ +SSL DOWNLOAD EXAMPLE + +Description: +Download file from Web server via https. + +Configuration: +Modify SSL_MAX_CONTENT_LEN in SSL config and configTOTAL_HEAP_SIZE in freertos config for large size file +Modify SERVER_HOST, SERVER_PORT and RESOURCE in example_ssl_download.c based on your SSL server + +[platform_opts.h] + #define CONFIG_EXAMPLE_SSL_DOWNLOAD 1 + +Execution: +Can make automatical Wi-Fi connection when booting by using wlan fast connect example. +A ssl download example thread will be started automatically when booting. + diff --git a/RTL00_SDKV35a/component/common/example/uart_firmware_update/example_uart_update.c b/RTL00_SDKV35a/component/common/example/uart_firmware_update/example_uart_update.c new file mode 100644 index 0000000..001772d --- /dev/null +++ b/RTL00_SDKV35a/component/common/example/uart_firmware_update/example_uart_update.c @@ -0,0 +1,64 @@ + +#include "example_uart_update.h" + +int is_update_image_enable(gpio_t *gpio_uart_update_eable) +{ + + HAL_GPIO_PIN GPIO_Pin; + u32 active_state; +// gpio_t gpio_uart_update_eable; + int ret = 0; +#if 0 + GPIO_Pin.pin_name = 0xC4; + //low active + GPIO_Pin.pin_mode = DIN_PULL_HIGH; + active_state = GPIO_PIN_LOW; + + HAL_GPIO_Init(&GPIO_Pin); + + if (HAL_GPIO_ReadPin(&GPIO_Pin) == active_state) + ret = 0; + else + ret = 1; + + HAL_GPIO_DeInit(&GPIO_Pin); +#else + gpio_init(gpio_uart_update_eable, PIN_NAME); + gpio_dir(gpio_uart_update_eable, PIN_INPUT); // Direction: Input + gpio_mode(gpio_uart_update_eable, PullUp); // Pull-High +// ret = gpio_read(&gpio_uart_update_eable); +#endif + + return ret; +} +void example_uart_update_thread(void *param) +{ + int count = 0; + gpio_t gpio_uart_update_eable; + + is_update_image_enable(&gpio_uart_update_eable); + //polling MAX_WAIT_TIME*50ms + while(count <= MAX_WAIT_TIME) + { + printf(" waitting update enable\r\n"); + if(gpio_read(&gpio_uart_update_eable) == 0){ + printf(" update image enabled!\r\n"); + uart_ymodem(); + break; + } + else{ + RtlMsleepOS(50); + count++; + } + } + + vTaskDelete(NULL); +} + +void example_uart_update(void) +{ + if(xTaskCreate(example_uart_update_thread, ((const char*)"example_uart_update_thread"), 512, NULL, tskIDLE_PRIORITY + 2, NULL) != pdPASS) + printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__); +} + + diff --git a/RTL00_SDKV35a/component/common/example/uart_firmware_update/example_uart_update.h b/RTL00_SDKV35a/component/common/example/uart_firmware_update/example_uart_update.h new file mode 100644 index 0000000..eab8ea4 --- /dev/null +++ b/RTL00_SDKV35a/component/common/example/uart_firmware_update/example_uart_update.h @@ -0,0 +1,17 @@ +#ifndef UART_UPDATE_H +#define UART_UPDATE_H + +#include "PinNames.h" +#include "gpio_api.h" +#include "hal_gpio.h" +#include "osdep_api.h" + +#define PIN_NAME PC_2 +#define MAX_WAIT_TIME 100 + +void example_uart_update(); +int is_update_image_enable(gpio_t *gpio_uart_update_eable); +extern int uart_ymodem(void); + +#endif + diff --git a/RTL00_SDKV35a/component/common/example/uvc/example_uvc.c b/RTL00_SDKV35a/component/common/example/uvc/example_uvc.c new file mode 100644 index 0000000..03fd139 --- /dev/null +++ b/RTL00_SDKV35a/component/common/example/uvc/example_uvc.c @@ -0,0 +1,586 @@ + +/* +* V4L2 video capture example +*/ + +#include "FreeRTOS.h" +#include "task.h" +#include "example_uvc.h" +#include "videodev2.h" +#include "uvcvideo.h" +#include "v4l2_driver.h" +#include "mjpeg/mjpeg.h" +#include "rtsp/rtsp_api.h" +#include "sockets.h" +#include "lwip/netif.h" + +#include "uvc_intf.h" + +#include "section_config.h" +SDRAM_DATA_SECTION struct rtp_object rtp_payload[VIDEO_MAX_FRAME]; + +struct rtp_payload_queue payload_queue; + +void example_uvc(void) +{ + /*init payload queue*/ + INIT_LIST_HEAD(&payload_queue.wait_queue); + INIT_LIST_HEAD(&payload_queue.done_queue); + RtlMutexInit(&payload_queue.wait_mutex); + RtlMutexInit(&payload_queue.done_mutex); + RtlInitSema(&payload_queue.wait_sema, 0); + RtlInitSema(&payload_queue.done_sema, 0); + payload_queue.flush_err = 0; + uvc_stream_init(); +} + +void uvc_entry_handle(void *param) +{ + int i, ret, cnt; + struct stream_context *stream_ctx = (struct stream_context *)param; + struct uvc_buf_context buf; + struct rtp_object *payload; + + /*initialize rtp payload*/ + for(i = 0; i < VIDEO_MAX_FRAME; i++) + { + if(rtp_init_payload(stream_ctx, &rtp_payload[i]) < 0) + { + for(; i>=0; i--) + { + rtp_uninit_payload(stream_ctx, &rtp_payload[i]); + } + goto exit; + } + } + + if(uvc_set_param(stream_ctx, UVC_FORMAT_MJPEG, 640, 480, 30)<0) + goto exit; + + if(uvc_stream_on(stream_ctx)<0) + goto exit; + + /*do buffer queue & dequeue inside the loop*/ + payload_queue.flush_err = 0; + while(!(payload_queue.flush_err)) + { + memset(&buf, 0, sizeof(struct uvc_buf_context)); + ret = uvc_dqbuf(stream_ctx, &buf); + if(buf.index < 0) + continue;//empty buffer retrieved + if((uvc_buf_check(&buf)<0)||(ret < 0)){ + RTSP_ERROR("\n\rbuffer error!"); + ret = -ENOENT; + goto exit; + } + rtp_payload[buf.index].index = buf.index; + if(rtp_fill_payload(stream_ctx, &rtp_payload[buf.index], buf.data, buf.len) < 0) + goto exit; + + /*add rtp_payload into payload queue*/ + RtlDownMutex(&payload_queue.wait_mutex); + list_add_tail(&rtp_payload[buf.index].rtp_list, &payload_queue.wait_queue); + RtlUpMutex(&payload_queue.wait_mutex); + RtlUpSema(&payload_queue.wait_sema); + + //check if any rtp payload is queued in done_queue + while(RtlDownSemaWithTimeout(&payload_queue.done_sema, 5)==0) + { + if(payload_queue.flush_err) + goto exit; + } + if(!list_empty(&payload_queue.done_queue)) + { + RtlDownMutex(&payload_queue.done_mutex); + payload = list_first_entry(&payload_queue.done_queue, struct rtp_object, rtp_list); + if(payload == NULL) + { + RtlUpMutex(&payload_queue.done_mutex); + continue; + } + list_del_init(&payload->rtp_list); + RtlUpMutex(&payload_queue.done_mutex); + + buf.index = payload->index; + buf.data = payload->data; + buf.len = payload->len; + + ret = uvc_qbuf(stream_ctx, &buf); + if (ret < 0){ + RTSP_ERROR("\n\rread_frame mmap method enqueue buffer failed"); + ret = -ENOENT; + goto exit; + } + } + } + +exit: + uvc_stream_off(stream_ctx); + uvc_stream_free(stream_ctx); + + for(i = 0; i < VIDEO_MAX_FRAME; i++) + { + rtp_uninit_payload(stream_ctx, &rtp_payload[i]); + } + + //free payload_queue memory + INIT_LIST_HEAD(&payload_queue.wait_queue); + INIT_LIST_HEAD(&payload_queue.done_queue); + RtlMutexFree(&payload_queue.wait_mutex); + RtlMutexFree(&payload_queue.done_mutex); + RtlFreeSema(&payload_queue.wait_sema); + RtlFreeSema(&payload_queue.done_sema); + + printf("\n\rstream free success, delete task..."); + vTaskDelete(NULL); +} + + + +int uvc_rtp_init(struct rtsp_context *rtsp_ctx); +void uvc_rtsp_handle(void *param) +{ + struct stream_context *stream_ctx = (struct stream_context *)param; + struct rtsp_context *rtsp_ctx; + u8 *request_header; //buffer to hold rtsp request + struct sockaddr_in server_addr, client_addr; + int client_socket; + socklen_t client_addr_len = sizeof(struct sockaddr_in); + + fd_set read_fds; + struct timeval timeout; + int ok; + rtsp_ctx = malloc(sizeof(struct rtsp_context)); + if(rtsp_ctx == NULL) + { + RTSP_ERROR("\n\rrtsp context is NULL"); + goto exit; + } + request_header = malloc(512); + if(request_header == NULL) + { + RTSP_ERROR("\n\rallocate request header buffer failed"); + goto exit; + } + // Delay to wait for IP by DHCP + vTaskDelay(500); + /*init rtsp context to unicast udp mode*/ + if(rtsp_context_init(rtsp_ctx) < 0) + goto exit; + + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = *(uint32_t *)(rtsp_ctx->connect_ctx.server_ip)/*htonl(INADDR_ANY)*/; + server_addr.sin_port = htons(rtsp_ctx->connect_ctx.port); + + if(bind(rtsp_ctx->connect_ctx.socket_id, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { + RTSP_ERROR("\n\rCannot bind stream socket"); + goto exit; + } + listen(rtsp_ctx->connect_ctx.socket_id, 1); + printf("\n\rrtsp context initialized!"); + + stream_ctx->protoCtx = (void *)rtsp_ctx; + rtsp_ctx->stream_ctx = (void *)stream_ctx; + + /*start rtp task*/ + uvc_rtp_init(rtsp_ctx); + + + while(stream_ctx->allowStream) + { + FD_ZERO(&read_fds); + timeout.tv_sec = 1; + timeout.tv_usec = 0; + FD_SET(rtsp_ctx->connect_ctx.socket_id, &read_fds); + if(select(1, &read_fds, NULL, NULL, &timeout)) + { + client_socket = accept(rtsp_ctx->connect_ctx.socket_id,(struct sockaddr *)&client_addr, &client_addr_len); + if(client_socket < 0) + { + RTSP_ERROR("client_socket error:%d\r\n", client_socket); + close(client_socket); + continue; + } + *(rtsp_ctx->connect_ctx.remote_ip + 3) = (unsigned char) (client_addr.sin_addr.s_addr >> 24); + *(rtsp_ctx->connect_ctx.remote_ip + 2) = (unsigned char) (client_addr.sin_addr.s_addr >> 16); + *(rtsp_ctx->connect_ctx.remote_ip + 1) = (unsigned char) (client_addr.sin_addr.s_addr >> 8); + *(rtsp_ctx->connect_ctx.remote_ip) = (unsigned char) (client_addr.sin_addr.s_addr ); + + while(stream_ctx->allowStream) + { + + + read(client_socket, request_header, 512); + rtsp_readheader(request_header); + if(*request_header == 0) + { + + //Do I need to send error response to client? + continue; + } + + + rtsp_getparam(rtsp_ctx, request_header); + switch(rtsp_ctx->rtsp_cmd) + { + + case(CMD_OPTIONS): + RTSP_PRINTF("\n\rReceive options command!"); + if(rtsp_ctx->state == RTSP_PLAYING) + break; + + rtsp_cmd_options(rtsp_ctx); + ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); + if (ok <= 0) + { + + + RTSP_ERROR("\n\rsend OPTIONS response failed!"); + goto exit; + } + break; + + + + case(CMD_DESCRIBE): + RTSP_PRINTF("\n\rReceive describe command!"); + if(rtsp_ctx->state == RTSP_PLAYING) + break; + + rtsp_cmd_describe(rtsp_ctx); + ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); + if (ok <= 0) + { + + + RTSP_ERROR("\n\rsend DESCRIBE response failed!"); + goto exit; + } + break; + + + + case(CMD_SETUP): + RTSP_PRINTF("\n\rReceive setup command!"); + if(rtsp_ctx->state == RTSP_PLAYING) + break; + + //fill transport parameter + rtsp_cmd_setup(rtsp_ctx); + ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); + if (ok <= 0) + { + + + RTSP_ERROR("\n\rsend SETUP response failed!"); + goto exit; + } + + + if(rtsp_ctx->state == RTSP_INIT) + { + + rtsp_ctx->state = RTSP_READY; + RTSP_PRINTF("\n\rstate changed from RTSP_INIT to RTSP_READY"); + }; + break; + + + case(CMD_TEARDOWN): + RTSP_PRINTF("\n\rReceive teardown command!"); + rtsp_ctx->state = RTSP_INIT; + rtsp_cmd_teardown(rtsp_ctx); + ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); + if (ok <= 0) + { + + + RTSP_ERROR("\n\rsend TEARDOWN response failed!"); + goto exit; + } + + + + + RTSP_PRINTF("\n\rstreaming teardown, state changed back to RTSP_INIT"); + /*have to wait until rtp server reinit*/ + vTaskDelay(1000); + goto out; + break; + + + case(CMD_PLAY): + RTSP_PRINTF("\n\rReceive play command!"); + if(rtsp_ctx->state == RTSP_PLAYING) + break; + + rtsp_cmd_play(rtsp_ctx); + ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); + if (ok <= 0) + { + + + RTSP_ERROR("\n\rsend PLAY response failed!"); + goto exit; + } + + + if(rtsp_ctx->state == RTSP_READY) + { + + rtsp_ctx->state = RTSP_PLAYING; + RTSP_PRINTF("\n\rstate changed from RTSP_READY to RTSP_PLAYING"); + rtsp_ctx->is_rtp_start = 1; + RtlUpSema(&rtsp_ctx->start_rtp_sema); + } + break; + + + + + case(CMD_PAUSE): + RTSP_PRINTF("\n\rReceive pause command!"); + rtsp_cmd_pause(rtsp_ctx); + ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); + if (ok <= 0) + { + + + RTSP_ERROR("\n\rsend PAUSE response failed!"); + goto exit; + } + + + if(rtsp_ctx->state == RTSP_PLAYING) + { + + rtsp_ctx->state = RTSP_READY; + RTSP_PRINTF("\n\rstate changed from RTSP_PLAYING to RTSP_READY"); + } + break; + default: + + + + RTSP_ERROR("\n\rReceive unrecognized command!"); + rtsp_cmd_error(rtsp_ctx); + ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); + if (ok <= 0) + { + + + RTSP_ERROR("\n\rsend ERROR response failed!"); + goto exit; + } + rtsp_ctx->state = RTSP_INIT; + } + if((rtsp_ctx->is_rtp_start == 0) && (rtsp_ctx->state == RTSP_PLAYING)) + { + + + rtsp_ctx->state = RTSP_INIT; + RtlUpSema(&rtsp_ctx->start_rtp_sema); + } + + + } +out: + rtsp_ctx->state = RTSP_INIT; + close(client_socket); + } + + } +exit: + if((rtsp_ctx->is_rtp_start) == 1){ + RtlUpSema(&rtsp_ctx->start_rtp_sema); + } + printf("\n\rrtsp -> Available heap 0x%x\n", xPortGetFreeHeapSize()); + close(client_socket); + close(rtsp_ctx->connect_ctx.socket_id); + if(request_header != NULL) + free(request_header); + /*wait until rtp task being destroyed*/ + while((rtsp_ctx->is_rtp_start)) + { + vTaskDelay(100); + } + rtsp_context_free(rtsp_ctx); + if(rtsp_ctx != NULL) + free(rtsp_ctx); + RTSP_ERROR("\n\rkill rtsp server thread!"); + //printf("Available heap 0x%x\n", xPortGetFreeHeapSize()); + //thread must be killed after server socket is terminated + vTaskDelete(NULL); + +} + + +void uvc_rtp_udp_init(struct stream_context *stream_ctx) +{ + + struct rtsp_context *rtsp_ctx = (struct rtsp_context *)stream_ctx->protoCtx; + struct uvc_buf_context buf; + struct rtp_object *payload; + struct sockaddr_in rtp_addr; + int rtp_socket; + int i, ret; + socklen_t addrlen = sizeof(struct sockaddr_in); + int rtp_port; + /* varibles for recording statistic use*/ + unsigned int cnt, total, total_time, time1, time2, time3; + cnt = total = total_time = time1 = time2 = time3 = 0; + /*init rtp socket*/ + rtp_socket = socket(AF_INET, SOCK_DGRAM, 0); + rtp_port = rtsp_ctx->transport.serverport_min; + memset(&rtp_addr, 0, addrlen); + rtp_addr.sin_family = AF_INET; + rtp_addr.sin_addr.s_addr = *(uint32_t *)(rtsp_ctx->connect_ctx.server_ip); + rtp_addr.sin_port = htons((u16)rtp_port); + if (bind(rtp_socket,(struct sockaddr *)&rtp_addr, addrlen)<0) { + RTSP_ERROR("bind failed\r\n"); + goto exit; + } + + +restart: + while((stream_ctx->isProcess)&&(rtsp_ctx->state == RTSP_PLAYING)) + { + if(RtlDownSemaWithTimeout(&payload_queue.wait_sema, 5)==0) + continue; + time1 = time3; + time2 = xTaskGetTickCount(); + /*send rtp payload*/ + if(!list_empty(&payload_queue.wait_queue)) + { + RtlDownMutex(&payload_queue.wait_mutex); + payload = list_first_entry(&payload_queue.wait_queue, struct rtp_object, rtp_list); + if(payload == NULL) + { + RtlUpMutex(&payload_queue.wait_mutex); + continue; + } + list_del_init(&payload->rtp_list); + RtlUpMutex(&payload_queue.wait_mutex); + + if(rtsp_ctx->state == RTSP_PLAYING) + { + + payload->connect_ctx.socket_id = rtp_socket; + payload->connect_ctx.port = (u16)rtsp_ctx->transport.clientport_min; + payload->connect_ctx.server_ip = rtsp_ctx->connect_ctx.server_ip; + payload->connect_ctx.remote_ip = rtsp_ctx->connect_ctx.remote_ip; + + ret = rtp_udp_send(stream_ctx, payload); + } + + //dequeue the this buffer from payload_queue + RtlDownMutex(&payload_queue.done_mutex); + list_add_tail(&payload->rtp_list, &payload_queue.done_queue); + RtlUpMutex(&payload_queue.done_mutex); + RtlUpSema(&payload_queue.done_sema); + + time3 = xTaskGetTickCount(); + cnt ++; + total += payload->len; + total_time += (time3-time1); + if(cnt == 100) + { + /* print statistics info */ + /*1.average frame size(kB) T:2.time waited for next frame sending start(ms)-3.udp sending time(ms) 4.frame rate(fps)*/ + printf("\n\r%dkB T:%d-%d %dfps", (total/102400), (time2 - time1), (time3 - time2), (100000/total_time)); + cnt = 0; + total = 0; + total_time = 0; + } + } + + } + mdelay(1000); + if(rtsp_ctx->state == RTSP_READY) + { + goto restart; + } + +exit: + close(rtp_socket); +} + +void uvc_rtp_tcp_init(struct stream_context *stream_ctx) +{ +} + +void uvc_rtp_multi_init(struct stream_context *stream_ctx) +{ +} + +void uvc_rtp_handle(void *param) +{ + struct stream_context *stream_ctx = (struct stream_context *)param; + struct rtsp_context *rtsp_ctx = (struct rtsp_context *)stream_ctx->protoCtx; + + /*go down when rtsp state change to playing*/ + while(1) + { + RtlDownSema(&rtsp_ctx->start_rtp_sema); + /*check rtp cast mode*/ + if(rtsp_ctx->state == RTSP_PLAYING) + { + printf("\n\rrtp start..."); + switch(rtsp_ctx->transport.castMode) + { + case(UNICAST_UDP_MODE): + uvc_rtp_udp_init(stream_ctx); + break; + case(MULTICAST_MODE): + uvc_rtp_tcp_init(stream_ctx); + break; + case(UNICAST_TCP_MODE): + uvc_rtp_multi_init(stream_ctx); + break; + default: + RTSP_ERROR("\r\n unknown streaming mode! Go back to RTSP_INIT state\n"); + rtsp_ctx->is_rtp_start = 0; + break; + } + }else{ + + break; + } + printf("\n\rrtp stop..."); + } + rtsp_ctx->is_rtp_start = 0; + RTSP_ERROR("\n\rkill rtp server thread!"); + //printf("Available heap 0x%x\n", xPortGetFreeHeapSize()); + vTaskDelete(NULL); +} + + +int uvc_rtp_init(struct rtsp_context *rtsp_ctx) +{ + struct stream_context *stream_ctx = (struct stream_context *)rtsp_ctx->stream_ctx; + + if(xTaskCreate(uvc_rtp_handle, ((const signed char*)"uvc_rtp_handle"), 2048, (void *)stream_ctx, tskIDLE_PRIORITY + 2, NULL) != pdPASS) { + RTSP_ERROR("\r\n uvc_rtp_handle: Create Task Error\n"); + return -1; + } + return 0; +} + +void uvc_task_init(void * param) +{ + +/*entry to start uvc streaming -- dequeue uvc buffer*/ + if(xTaskCreate(uvc_entry_handle, ((const signed char*)"uvc_entry_handle"), 1024, param, tskIDLE_PRIORITY + 2, NULL) != pdPASS) { + UVC_ERROR("\r\n uvc_entry_handle: Create Task Error\n"); + } + +/*entry to start rtsp server*/ +#if UVC_RTSP_EN + if(xTaskCreate(uvc_rtsp_handle, ((const signed char*)"uvc_rtsp_handle"), 4096, param, tskIDLE_PRIORITY + 2, NULL) != pdPASS) { + RTSP_ERROR("\r\n uvc_rtsp_handle: Create Task Error\n"); + } +#endif +} + + +/************************************************************end of rtsp/rtp with motion-jpeg************************************************/ diff --git a/RTL00_SDKV35a/component/common/example/uvc/example_uvc.h b/RTL00_SDKV35a/component/common/example/uvc/example_uvc.h new file mode 100644 index 0000000..12c2742 --- /dev/null +++ b/RTL00_SDKV35a/component/common/example/uvc/example_uvc.h @@ -0,0 +1,25 @@ +#ifndef EXAMPLE_UVC_H +#define EXAMPLE_UVC_H + +#include +#include "platform_opts.h" +#include "dlist.h" +#include "osdep_api.h" + +#define UVC_RTSP_EN 1 + +//example structure to handle rtp_object operation in queue +struct rtp_payload_queue +{ + struct list_head wait_queue; + _Mutex wait_mutex; + struct list_head done_queue; + _Mutex done_mutex; + _Sema wait_sema; //up it whenever a rtp payload queue in wait_queue + _Sema done_sema; //up it whenever a rtp payload queue in done_queue + int flush_err; +}; + +void example_uvc(void); + +#endif /* EXAMPLE_UVC_H */ \ No newline at end of file diff --git a/RTL00_SDKV35a/component/common/example/uvc/readme.txt b/RTL00_SDKV35a/component/common/example/uvc/readme.txt new file mode 100644 index 0000000..98298c4 --- /dev/null +++ b/RTL00_SDKV35a/component/common/example/uvc/readme.txt @@ -0,0 +1,8 @@ + +THis is an example for USB Video Capture specifically for motion-jpeg capturing. + +Please MAKE SURE to reserve enough heap size for UVC by raising configTOTAL_HEAP_SIZE in freeRTOSconfig.h & turning off some functions (e.g. WPS, JDSMART, ATcmd for internal and system) since image frame storing could consume quite large memory space. + +TO switch on UVC example, make sure CONFIG_USB_EN is enabled (in platform_autoconf.h) & set CONFIG_EXAMPLE_UVC to 1 (in platform_opts.h). + +TO combine uvc with rtsp server, make sure wlan module is enabled & set UVC_WLAN_TRANSFER to 1 (in example_uvc.h). \ No newline at end of file diff --git a/RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_host.c b/RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_host.c new file mode 100644 index 0000000..edf1a5c --- /dev/null +++ b/RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_host.c @@ -0,0 +1,2192 @@ +/* +*/ +#include "rtl8195a.h" +#include "rtl8195a_sdio_host.h" +//------------------------------------------------------------------------- +// Function declarations +/* +signed int SdioHostIsTimeout(uint32_t StartCount, uint32_t TimeoutCnt); +void SdioHostSendCmd(SDIO_HOST_CMD *Cmd); +signed int SdioHostGetResponse(void *Data, int RspType); +void SdioHostSdBusPwrCtrl(uint8_t En, int a2); +int SdioHostSdClkCtrl(void *Data, int En, int Divisor); +int SdioHostChkDataLineActive(uint32_t Timeout); +int SdioHostChkCmdInhibitCMD(uint32_t Timeout); +int SdioHostChkCmdInhibitDAT(uint32_t Timeout); +uint32_t SdioHostIsrHandle(void *Data); +int HalSdioHostDeInitRtl8195a(void *Data); +int HalSdioHostEnableRtl8195a(void *Data); +int HalSdioHostDisableRtl8195a(void *Data); +signed int HalSdioHostIrqInitRtl8195a(void *Data); +signed int HalSdioHostInitHostRtl8195a(void *Data); +int HalSdioHostStopTransferRtl8195a(void *Data, uint32_t a2); +signed int SdioHostErrIntRecovery(void *Data, int a2, signed int a3); +signed int SdioHostChkXferComplete(void *Data, uint32_t Timeout, signed int a3); +signed int SdioHostChkCmdComplete(void *Data, uint32_t Timeout); +int SdioHostCardSelection(void *Data, int Select, int a3); +int SdioHostGetCSD(void *Data, uint32_t a2); +int HalSdioHostReadBlocksDmaRtl8195a(int result, uint32_t a2, int64 a3, uint32_t BlockCnta); +int HalSdioHostWriteBlocksDmaRtl8195a(int result, uint32_t a2, int64 a3, uint32_t BlockCnta); +int SdioHostSwitchFunction(void *Data, int Mode, int Fn2Sel, int Fn1Sel, uint8_t *StatusBuf); +int HalSdioHostGetCardStatusRtl8195a(void *Data, uint32_t a2, int a3); +signed int HalSdioHostInitCardRtl8195a(void *Data, int a2, int a3); +int HalSdioHostGetSdStatusRtl8195a(void *Data, uint32_t a2, int a3); +signed int HalSdioHostChangeSdClockRtl8195a(void *Data, int Frequency); +int HalSdioHostEraseRtl8195a(uint64_t EndAddr, int64 a2, int64 EndAddra); +signed int HalSdioHostGetWriteProtectRtl8195a(void *Data, uint32_t a2, int a3); +int HalSdioHostSetWriteProtectRtl8195a(void *Data, int Setting); +*/ +// int DiagPrintf(const char *, ...); weak +// int VectorIrqDisRtl8195A(u32); weak +// int VectorIrqUnRegisterRtl8195A(u32); weak +// int HalPinCtrlRtl8195A(u32, u32, u32); weak +// int VectorIrqRegisterRtl8195A(void); weak +// int VectorIrqEnRtl8195A(u32); weak +// int HalDelayUs(u32); weak + +//------------------------------------------------------------------------- +// Data declarations + +// extern _UNKNOWN HalTimerOp; weak +// extern _UNKNOWN ConfigDebugInfo; weak +// extern _UNKNOWN ConfigDebugErr; weak + + +//----- +int SdioHostIsTimeout(uint32_t StartCount, uint32_t TimeoutCnt) +{ + u32 t1, t2; + int result; + + t1 = HalTimerOp.HalTimerReadCount(1); + t2 = StartCount - t1; + if(StartCount < t1) t2--; + if (TimeoutCnt >= t2 ) result = 0; + else result = 2; + return result; +} + +//----- +void SdioHostSendCmd(SDIO_HOST_CMD *Cmd) +{ + int v1; + + v1 = *(u8 *)&Cmd->CmdFmt & 0x3B | *(u8 *)&Cmd->CmdFmt & 0xC0 | ((*((u8 *)&Cmd->CmdFmt + 1) & 0x3F) << 8); + v40058008 = Cmd->Arg; + v4005800E = v1; +} + +//----- +signed int SdioHostGetResponse(void *Data, int RspType) +{ + signed int result; + + if ( Data ) + { + *((u32 *)Data + 5) = v40058010; + *((u32 *)Data + 6) = v40058014; + if ( RspType == 1 ) + { + *((u32 *)Data + 7) = v40058018; + *((u32 *)Data + 8) = v4005801C; + } + result = 0; + } + else + { + result = 3; + } + return result; +} + +//----- +void SdioHostSdBusPwrCtrl(uint8_t En, int a2) +{ + char v2; // r3@4 + + v40058029 &= 0xFEu; + if ( v40058040 & 0x1000000 ) + { + DBG_SDIO_WARN("Supply SD bus voltage: 3.3V\n", ConfigDebugInfo << 21); + v2 = 14; +LABEL_9: + v40058029 = v2; + goto LABEL_16; + } + if ( v40058040 & 0x2000000 ) + { + DBG_SDIO_WARN("Supply SD bus voltage: 3.0V\n", a2, v40058040 << 6); + v2 = 12; + goto LABEL_9; + } + if ( v40058040 & 0x4000000 ) + { + DBG_SDIO_WARN("Supply SD bus voltage: 1.8V\n", 32 * v40058040, ConfigDebugInfo << 21); + v2 = 10; + goto LABEL_9; + } + DBG_SDIO_ERR("No supported voltage\n", 32 * v40058040, v40058040 << 6); +LABEL_16: + v40058029 |= 1u; +} + + +//----- +int SdioHostSdClkCtrl(void *Data, int En, int Divisor) +{ + u8 *v3; // r3@1 + int result; // r0@1 + char v5; // r2@7 + + v3 = Data; + result = v40058024 & 3; + if ( v40058024 & 3 ) + { + result = 1; + } + else + { + if ( !En ) + { + v4005802C &= 0xFFFBu; + return 0; + } + v4005802C &= 0xFFFBu; + v4005802C = v4005802C | (u16)((u16)Divisor << 8); + v4005802C |= 4u; + if ( Divisor == 8 ) + { + v5 = 4; + goto LABEL_23; + } + if ( (unsigned int)Divisor > 8 ) + { + if ( Divisor == 32 ) + { + v5 = 2; + goto LABEL_23; + } + if ( (unsigned int)Divisor > 0x20 ) + { + if ( Divisor == 64 ) + { + v5 = 1; + goto LABEL_23; + } + if ( Divisor == 128 ) + { + v3[133] = 0; + return result; + } + } + else if ( Divisor == 16 ) + { + v5 = 3; + goto LABEL_23; + } + } + else + { + if ( Divisor == 1 ) + { + v5 = 7; + goto LABEL_23; + } + if ( (unsigned int)Divisor < 1 ) + { + v5 = 8; +LABEL_23: + v3[133] = v5; + return result; + } + if ( Divisor == 2 ) + { + v5 = 6; + goto LABEL_23; + } + if ( Divisor == 4 ) + { + v5 = 5; + goto LABEL_23; + } + } + + DBG_SDIO_ERR("Unsupported SDCLK divisor !!\n"); + return 0; + } + } + return result; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (000001E4) -------------------------------------------------------- +int SdioHostChkDataLineActive(uint32_t Timeout) +{ + uint32_t v1; // r4@1 + int result; // r0@2 + + v1 = (*((int ( **)(u32))&HalTimerOp + 2))(1); + do + { + result = v40058024 & 4; + if ( !(v40058024 & 4) ) break; + result = SdioHostIsTimeout(v1, 3225); + } + while ( result != 2 ); + return result; +} + +//----- (0000021C) -------------------------------------------------------- +int SdioHostChkCmdInhibitCMD(uint32_t Timeout) +{ + uint32_t v1; // r4@1 + int result; // r0@2 + + v1 = (*((int ( **)(u32))&HalTimerOp + 2))(1); + do + { + result = v40058024 & 1; + if ( !(v40058024 & 1) ) + break; + result = SdioHostIsTimeout(v1, 3225); + } + while ( result != 2 ); + return result; +} + +//----- (00000254) -------------------------------------------------------- +int SdioHostChkCmdInhibitDAT(uint32_t Timeout) +{ + uint32_t v1; // r4@1 + int result; // r0@2 + + v1 = (*((int ( **)(u32))&HalTimerOp + 2))(1); + do + { + result = v40058024 & 2; + if ( !(v40058024 & 2) ) + break; + result = SdioHostIsTimeout(v1, 3225); + } + while ( result != 2 ); + return result; +} + +//----- (0000028C) -------------------------------------------------------- +uint32_t SdioHostIsrHandle(void *Data) +{ + int v1; // r5@1 + u32 *v2; // r4@1 + uint8_t v3; // r0@7 + int v4; // r1@7 + void ( *v5)(u32); // r3@7 + void ( *v6)(u32); // r3@10 + uint32_t result; // r0@14 + + v1 = v40058030; + v40058038 = 0; + v2 = Data; + if ( v40058030 ) { + if ( v40058030 << 31 < 0 ) + *((u8 *)Data + 128) = 1; + if ( v1 << 30 < 0 ) + *((u8 *)Data + 129) = 1; + if ( v1 & NOR_INT_STAT_CARD_INSERT) // 0x40 + { + v3 = SdioHostSdClkCtrl(Data, 1, 64); + SdioHostSdBusPwrCtrl(v3, v4); + v5 = (void ( *)(u32))v2[35]; + if ( v5 ) v5(v2[37]); + } + if ( v1 & NOR_INT_STAT_CARD_REMOVAL) // 0x80 + { + v40058029 &= 0xFEu; + SdioHostSdClkCtrl(v2, 0, 0); + v6 = (void ( *)(u32))v2[36]; + if ( v6 ) + v6(v2[38]); + } + if ( v1 & NOR_INT_STAT_ERR_INT) // 0x8000 ) + { + v4005803A = 0; + *((u8 *)v2 + 130) = 1; + } + } + v40058034 = 195; + result = 0; + v40058038 = 195; + return result; +} + +//----- (00000328) -------------------------------------------------------- +HAL_Status HalSdioHostDeInitRtl8195a(IN VOID *Data) +{ + void *v1; // r5@1 + int v2; // r4@1 + + PHAL_SDIO_HOST_ADAPTER v1 = Data; + v40058029 &= 0xFEu; + v2 = SdioHostSdClkCtrl(Data, 0, 0); + if ( !v2 ) + { + if ( v1 ) + { + VectorIrqDisRtl8195A(v1); + VectorIrqUnRegisterRtl8195A(v1); + v4005802C &= 0xFFFEu; + v40059000 &= 0xFFFFFBFF; + v40000214 &= 0xFFFFFFFB; + HalPinCtrlRtl8195A(65, 0, 0); + v40000240 &= 0xFFFFFFF7; + v40000240 &= 0xFFFFFFFB; + } + else + { + v2 = 3; + } + } + return v2; +} +// 23DC: using guessed type int VectorIrqDisRtl8195A(u32); +// 23E0: using guessed type int VectorIrqUnRegisterRtl8195A(u32); +// 23E4: using guessed type int HalPinCtrlRtl8195A(u32, u32, u32); + +//----- (000003C0) -------------------------------------------------------- +HAL_Status HalSdioHostEnableRtl8195a(IN VOID *Data) // // PHAL_SDIO_HOST_ADAPTER Data +{ + v40000240 |= 4u; + v40000240 |= 8u; + v4005802C |= 1u; + while ( !(v4005802C & 2) ) + ; + return SdioHostSdClkCtrl(Data, 1, 1); +} + +//----- (000003F8) -------------------------------------------------------- +HAL_Status HalSdioHostDisableRtl8195a(IN VOID *Data) +{ + int result; // r0@1 + + result = SdioHostSdClkCtrl(Data, 0, 0); + if ( !result ) + { + v4005802C &= 0xFFFEu; + v40000240 &= 0xFFFFFFF7; + v40000240 &= 0xFFFFFFFB; + } + return result; +} + +//----- HalSdioHostIrqInitRtl8195a +HAL_Status HalSdioHostIrqInitRtl8195a(IN VOID *Data) // PIRQ_HANDLE Data +{ + HAL_Status result; + PIRQ_HANDLE v1 = Data; + if (v1) { + v1->Data = Data; + v1->IrqNum = SDIO_HOST_IRQ; + v1->IrqFun = SdioHostIsrHandle; + v1->Priority = 6; + VectorIrqRegisterRtl8195A(); + VectorIrqEnRtl8195A((PIRQ_HANDLE) v1); + result = HAL_OK; + } + else result = HAL_ERR_PARA; + return result; +} + +//----- HalSdioHostInitHostRtl8195a +HAL_Status HalSdioHostInitHostRtl8195a(IN VOID *Data) +{ + HAL_WRITE32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0, + HAL_READ32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0) & (~BIT_SOC_ACTCK_SDIO_DEV_EN)); + HAL_WRITE32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN, + HAL_READ32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN) & (~BIT_SOC_HCI_SDIOD_ON_EN)); + + HAL_WRITE32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN, + HAL_READ32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN) & (~BIT_SOC_HCI_SDIOD_OFF_EN)); + + HAL_WRITE32(PERI_ON_BASE, REG_HCI_PINMUX_CTRL, + HAL_READ32(PERI_ON_BASE, REG_HCI_PINMUX_CTRL) & (~BIT_HCI_SDIOD_PIN_EN)); + + HAL_WRITE32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0, + HAL_READ32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0) | BIT_SOC_ACTCK_SDIO_HST_EN); + HAL_WRITE32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0, + HAL_READ32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0) | BIT_SOC_SLPCK_SDIO_HST_EN); + HalPinCtrlRtl8195A(SDIOH, 0, 1); + HAL_WRITE32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN, + HAL_READ32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN) | BIT_SOC_HCI_SDIOH_EN); + HAL_SDIO_HOST_WRITE8(REG_SDIO_HOST_SW_RESET, + HAL_SDIO_HOST_READ8(REG_SDIO_HOST_SW_RESET) | 1); //4005802F |= 1; + int x = 1000; + while(HAL_SDIO_HOST_READ8(REG_SDIO_HOST_SW_RESET) & 1 ) { + if(x-- == 0) { + DBG_SDIO_ERR("SD host initialization FAIL !!\n"); + return HAL_TIMEOUT; + } + } + HalSdioHostIrqInitRtl8195a(Data); + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_ERROR_INT_STATUS_EN, 195);// 40058034 = 195; + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_NORMAL_INT_SIG_EN, 195);// 40058038 = 195; + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_ERROR_INT_STATUS_EN, 127);// 40058036 = 127; + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_ERROR_INT_SIG_EN, 127);// 4005803A = 127; + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_CLK_CTRL, + HAL_SDIO_HOST_READ16(REG_SDIO_HOST_CLK_CTRL) | 1);// 4005802C |= 1; + x = 1000; + while ( !(HAL_SDIO_HOST_READ16(REG_SDIO_HOST_CLK_CTRL) & 2) ) { + if(x-- == 0) { + DBG_SDIO_ERR("SD host initialization FAIL !!\n"); + return HAL_TIMEOUT; + } + } + HAL_WRITE32(SYSTEM_CTRL_BASE, 0x59000, + HAL_READ32(SYSTEM_CTRL_BASE, 0x59000) | 0x400); // 40059000 |= 0x400; + if (HAL_SDIO_HOST_READ32(REG_SDIO_HOST_CAPABILITIES) & 0x80000 ) + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_HOST_CTRL, 16); //40058028 = 16; + HAL_SDIO_HOST_WRITE8(REG_SDIO_HOST_TIMEOUT_CTRL, 14); //4005802E = 14; + return 0; +} + +//----- (00000578) -------------------------------------------------------- +HAL_Status HalSdioHostStopTransferRtl8195a(IN VOID *Data) +{ + u8 *v2; // r4@1 + int result; // r0@2 + char v4; // r2@4 + uint32_t v5; // r1@4 + signed int v6; // r2@4 + SDIO_HOST_CMD Cmd; // [sp+0h] [bp-10h]@1 + + *(u32 *)&Cmd.CmdFmt = Data; + Cmd.Arg = a2; + v2 = Data; + if ( Data ) + { + result = SdioHostChkCmdInhibitCMD((uint32_t)Data); + if ( !result ) + { + result = SdioHostChkCmdInhibitDAT(0); + if ( !result ) + { + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT)((*(u8 *)&Cmd.CmdFmt | 0x1B) & 0xDF | 0xC0); + v4 = *((u8 *)&Cmd.CmdFmt + 1); + v2[128] = 0; + v2[129] = 0; + Cmd.Arg = 0; + *((u8 *)&Cmd.CmdFmt + 1) = v4 & 0xC0 | 0xC; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete(v2, v5); + if ( !result ) + result = SdioHostChkXferComplete(v2, 0x1388u, v6); + } + } + } + else + { + result = 3; + } + return result; +} + +//----- (000005D8) -------------------------------------------------------- +signed int SdioHostErrIntRecovery(void *Data, int a2, signed int a3) +{ + u8 *v3; // r6@1 + __int16 v4; // r5@4 + int v5; // r3@5 + const char *v6; // r0@11 + signed int result; // r0@13 + int v8; // r3@15 + int v9; // r0@24 + const char *v10; // r0@32 + + v3 = Data; + if ( !Data ) + return 3; + DBG_SDIO_ERR("Recovering error interrupt...\n", a2, a3); + v4 = v40058032; + if ( v40058032 << 28 ) + { + v4005802F |= 2u; + v5 = 0; + while ( 1 ) + { + ++v5; + a2 = v4005802F << 30; + if ( !(v4005802F & 2) ) break; + a2 = 1001; + if ( v5 == 1001 ) + goto LABEL_14; + } + if ( v5 == 1000 ) + { + DBG_SDIO_ERR("CMD line reset timeout !!\n"); + return 2; + } + } +LABEL_14: + if ( v40058032 & 0x70 ) + { + v4005802F |= 4u; + v8 = 0; + while ( 1 ) + { + ++v8; + a2 = v4005802F << 29; + if ( !(v4005802F & 4) ) + break; + a2 = 1001; + if ( v8 == 1001 ) + goto LABEL_22; + } + if ( v8 == 1000 ) + { + DBG_SDIO_ERR("DAT line reset timeout !!\n"); + return 2; + } + } +LABEL_22: + DBG_SDIO_ERR("Error interrupt status: 0x%04X\n", v40058032); + v40058032 = v4; + v3[130] = 0; + v9 = HalSdioHostStopTransferRtl8195a(v3, a2); + if ( !v9 ) + { + while ( 1 ) + { + ++v9; + if ( !(v40058024 & 3) ) + break; + if ( v9 == 1001 ) + goto LABEL_30; + } + if ( v9 == 1000 ) + return 2; +LABEL_30: + if ( v40058032 << 28 ) + { + DBG_SDIO_ERR("Non-recoverable error(1) !!\n"); +LABEL_33: + DiagPrintf(v10); + goto LABEL_34; + } + } + else + { + if ( v40058032 & 0x10 ) + { + DBG_SDIO_ERR("Non-recoverable error(2) !!\n"); + goto LABEL_34; + } + HalDelayUs(50); + if ( (v40058024 & 0xF00000) == 15728640 ) + { + DBG_SDIO_ERR("Recoverable error...\n"); + result = 16; + goto LABEL_44; + } + DBG_SDIO_ERR("Non-recoverable error(3) !!\n"); + goto LABEL_34; + } + } +LABEL_34: + result = 238; +LABEL_44: + v4005803A = 127; + return result; + } + DBG_SDIO_ERR("Stop transmission error !!\n"); + return 238; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); +// 23F0: using guessed type int HalDelayUs(u32); + +//----- (00000748) -------------------------------------------------------- +signed int SdioHostChkXferComplete(void *Data, uint32_t Timeout, signed int a3) +{ + uint32_t v3; // r6@1 + u8 *v4; // r4@1 + uint32_t v5; // r5@3 + uint32_t v6; // r7@3 + signed int result; // r0@9 + + v3 = Timeout; + v4 = Data; + if ( Data ) + { + if ( Timeout - 1 > 0xFFFFFFFD ) + { + v6 = 0; + v5 = 0; + } + else + { + v5 = 1000 * Timeout / 0x1F; + v6 = (*((int ( **)(u32))&HalTimerOp + 2))(1); + } + do + { + while ( 1 ) + { + if ( v4[129] && v40058024 & 0x100000 ) + return 0; + if ( v4[130] ) + return SdioHostErrIntRecovery(v4, Timeout, a3); + if ( !v5 ) + break; + result = SdioHostIsTimeout(v6, v5); + if ( result == 2 ) + return result; + } + } + while ( v3 ); + result = 1; + } + else + { + result = 3; + } + return result; +} + +//----- (000007C4) -------------------------------------------------------- +signed int SdioHostChkCmdComplete(void *Data, uint32_t Timeout) +{ + void *v2; // r4@1 + int v3; // r1@2 + signed int v4; // r2@2 + uint32_t v5; // r5@2 + signed int result; // r0@5 + + v2 = Data; + if ( Data ) + { + v5 = (*((int ( **)(u32, u32))&HalTimerOp + 2))(1, Timeout); + while ( !*((u8 *)v2 + 128) ) + { + if ( *((u8 *)v2 + 130) ) + return SdioHostErrIntRecovery(v2, v3, v4); + result = SdioHostIsTimeout(v5, 1612); + if ( result == 2 ) + return result; + } + result = 0; + } + else + { + result = 3; + } + return result; +} + +//----- (0000080C) -------------------------------------------------------- +int SdioHostCardSelection(void *Data, int Select, int a3) +{ + u8 *v3; // r4@1 + int result; // r0@3 + char v5; // r3@5 + int v6; // r3@5 + uint32_t v7; // r1@5 + signed int v8; // r2@5 + signed int v9; // r5@6 + char v10; // r3@11 + uint32_t v11; // r1@11 + SDIO_HOST_CMD Cmd; // [sp+0h] [bp-18h]@1 + int v13; // [sp+8h] [bp-10h]@1 + + *(u32 *)&Cmd.CmdFmt = Data; + Cmd.Arg = Select; + v13 = a3; + v3 = Data; + if ( Data ) + { + if ( Select == 1 ) + { + result = SdioHostChkCmdInhibitCMD((uint32_t)Data); + if ( !result ) + { + result = SdioHostChkCmdInhibitDAT(0); + if ( !result ) + { + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT)((*(u8 *)&Cmd.CmdFmt | 0x1B) & 0x1F); + v5 = *((u8 *)&Cmd.CmdFmt + 1); + v3[128] = 0; + *((u8 *)&Cmd.CmdFmt + 1) = v5 & 0xC0 | 7; + v6 = *((u16 *)v3 + 67); + v3[129] = 0; + Cmd.Arg = v6 << 16; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete(v3, v7); + if ( !result ) + { + v9 = SdioHostChkXferComplete(v3, 0x1388u, v8); + if ( v9 || (SdioHostGetResponse(v3, *(u8 *)&Cmd.CmdFmt & 3), v3[24] == 7) ) + { + result = v9; + } + else + { + DBG_SDIO_ERR("Command index error !!\n"); + result = 238; + } + } + } + } + } + else + { + result = SdioHostChkCmdInhibitCMD((uint32_t)Data); + if ( !result ) + { + *(u8 *)&Cmd.CmdFmt &= 4u; + v10 = *((u8 *)&Cmd.CmdFmt + 1); + v3[128] = 0; + Cmd.Arg = 0; + *((u8 *)&Cmd.CmdFmt + 1) = v10 & 0xC0 | 7; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete(v3, v11); + } + } + } + else + { + result = 3; + } + return result; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (000008FC) -------------------------------------------------------- +int SdioHostGetCSD(void *Data, uint32_t a2) +{ + void *v2; // r4@1 + int result; // r0@2 + int v4; // r3@3 + uint32_t v5; // r1@3 + signed int v6; // r6@3 + unsigned int v7; // r3@4 + unsigned int v8; // r2@4 + unsigned int v9; // r3@4 + unsigned int v10; // r2@4 + unsigned int v11; // r3@4 + unsigned int v12; // r2@4 + unsigned int v13; // r3@4 + SDIO_HOST_CMD Cmd; // [sp+0h] [bp-18h]@1 + + *(u32 *)&Cmd.CmdFmt = Data; + Cmd.Arg = a2; + v2 = Data; + if ( Data ) + { + result = SdioHostChkCmdInhibitCMD((uint32_t)Data); + if ( !result ) + { + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT)((*(u8 *)&Cmd.CmdFmt & 0xFC | 9) & 0xF); + *((u8 *)&Cmd.CmdFmt + 1) = *((u8 *)&Cmd.CmdFmt + 1) & 0xC0 | 9; + v4 = *((u16 *)v2 + 67); + *((u8 *)v2 + 128) = 0; + Cmd.Arg = v4 << 16; + SdioHostSendCmd(&Cmd); + v6 = SdioHostChkCmdComplete(v2, v5); + if ( !v6 ) + { + SdioHostGetResponse(v2, *(u8 *)&Cmd.CmdFmt & 3); + v7 = *((u32 *)v2 + 8); + *((u8 *)v2 + 127) = 1; + *((u8 *)v2 + 112) = v7 >> 16; + *((u8 *)v2 + 114) = v7; + v8 = v7 >> 8; + v9 = *((u32 *)v2 + 7); + *((u8 *)v2 + 113) = v8; + *((u8 *)v2 + 115) = BYTE3(v9); + *((u8 *)v2 + 116) = v9 >> 16; + *((u8 *)v2 + 118) = v9; + v10 = v9 >> 8; + v11 = *((u32 *)v2 + 6); + *((u8 *)v2 + 117) = v10; + *((u8 *)v2 + 119) = BYTE3(v11); + *((u8 *)v2 + 120) = v11 >> 16; + *((u8 *)v2 + 122) = v11; + v12 = v11 >> 8; + v13 = *((u32 *)v2 + 5); + *((u8 *)v2 + 121) = v12; + *((u8 *)v2 + 123) = BYTE3(v13); + *((u8 *)v2 + 124) = v13 >> 16; + *((u8 *)v2 + 125) = BYTE1(v13); + *((u8 *)v2 + 126) = v13; + } + result = v6; + } + } + else + { + result = 3; + } + return result; +} + +//----- (000009CC) -------------------------------------------------------- +HAL_Status HalSdioHostReadBlocksDmaRtl8195a(IN VOID *Data, IN u64 ReadAddr, IN u32 BlockCnt) +{ + int64 v4; // r4@1 + int v5; // r6@1 + int v6; // r7@3 + char v7; // r3@12 + uint32_t v8; // r1@12 + signed int v9; // r2@13 + int v10; // r1@16 + const char *v11; // r0@17 + char v12; // r3@20 + uint32_t v13; // r1@20 + signed int v14; // r2@23 + uint32_t v15; // r1@23 + SDIO_HOST_CMD Cmd; // [sp+0h] [bp-20h]@1 + + *(u32 *)&Cmd.CmdFmt = result; + Cmd.Arg = a2; + v4 = a3; + v5 = result; + if ( !result ) + return 3; + if ( BlockCnta >= 0x10000 ) + return 3; + v6 = *(u32 *)(result + 16); + if ( v6 << 30 || *(u32 *)(*(u32 *)(result + 16) + 4) << 30 ) + return 3; + if ( *(u8 *)(result + 132) ) + LODWORD(v4) = a3 >> 9; + while ( 1 ) + { + while ( 1 ) + { + v40058058 = v6; + v40058004 = 512; + if ( BlockCnta != 1 ) + break; + v4005800C = 17; +LABEL_18: + result = SdioHostChkCmdInhibitCMD(result); + if ( result ) + return result; + result = SdioHostChkDataLineActive(0); + if ( result ) + return result; + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT)((*(u8 *)&Cmd.CmdFmt & 0xF4 | 0x3A) & 0x3F); + v12 = *((u8 *)&Cmd.CmdFmt + 1); + *(u8 *)(v5 + 128) = 0; + *(u8 *)(v5 + 129) = 0; + *((u8 *)&Cmd.CmdFmt + 1) = v12 & 0xC0 | 0x11; + Cmd.Arg = v4; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete((void *)v5, v13); + if ( result ) + goto LABEL_21; + SdioHostGetResponse((void *)v5, *(u8 *)&Cmd.CmdFmt & 3); + result = SdioHostChkXferComplete((void *)v5, 0x1388u, v14); + if ( !result ) + return 0; + if ( result != 16 ) + { + if ( v40058032 & 0x200 ) + { + v40058032 = 512; + if ( HalSdioHostStopTransferRtl8195a((void *)v5, v15) ) + { + if ( ConfigDebugErr & 0x400 ) + { + v11 = "\r[SDIO Err]Stop transmission error!\n"; + goto LABEL_29; + } + } + } + return 238; + } + } + v40058006 = BlockCnta; + v4005800C = 55; + if ( BlockCnta <= 1 ) + goto LABEL_18; + result = SdioHostChkCmdInhibitCMD(result); + if ( result ) + return result; + result = SdioHostChkDataLineActive(0); + if ( result ) + return result; + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT)((*(u8 *)&Cmd.CmdFmt & 0xF4 | 0x3A) & 0x3F); + v7 = *((u8 *)&Cmd.CmdFmt + 1); + *(u8 *)(v5 + 128) = 0; + *(u8 *)(v5 + 129) = 0; + *(u8 *)(v5 + 130) = 0; + *((u8 *)&Cmd.CmdFmt + 1) = v7 & 0xC0 | 0x12; + Cmd.Arg = v4; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete((void *)v5, v8); + if ( !result ) + { + SdioHostGetResponse((void *)v5, *(u8 *)&Cmd.CmdFmt & 3); + result = SdioHostChkXferComplete((void *)v5, 0x1388u, v9); + if ( !result ) + break; + } +LABEL_21: + if ( result != 16 ) + return result; + } + if ( !(v40058032 & 0x20) ) + return 0; + v10 = ConfigDebugErr << 21; + if ( ConfigDebugErr & 0x400 ) + { + v11 = "\r[SDIO Err]Data CRC error!\n"; +LABEL_29: + DiagPrintf(v11, v10); + } + return 238; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (00000B78) -------------------------------------------------------- +HAL_Status +HalSdioHostWriteBlocksDmaRtl8195a(IN VOID *Data, IN u64 WriteAddr, IN u32 BlockCnt) +{ + uint32_t v4; // r4@1 + int v5; // r6@1 + int v6; // r8@3 + char v7; // r3@12 + uint32_t v8; // r1@12 + signed int v9; // r2@13 + char v10; // r3@25 + uint32_t v11; // r1@25 + signed int v12; // r2@28 + uint32_t v13; // r1@29 + SDIO_HOST_CMD Cmd; // [sp+0h] [bp-20h]@1 + + *(u32 *)&Cmd.CmdFmt = result; + Cmd.Arg = a2; + v4 = a3; + v5 = result; + if ( !result ) + return 3; + if ( BlockCnta >= 0x10000 ) + return 3; + v6 = *(u32 *)(result + 16); + if ( v6 & 3 || *(u32 *)(*(u32 *)(result + 16) + 4) << 30 ) + return 3; + if ( *(u8 *)(result + 132) ) + v4 = a3 >> 9; + while ( 1 ) + { + while ( 1 ) + { + v40058058 = v6; + v40058004 = 512; + if ( BlockCnta == 1 ) + { + v4005800C = 1; + goto LABEL_23; + } + v40058006 = BlockCnta; + v4005800C = 39; + if ( BlockCnta > 1 ) + break; +LABEL_23: + result = SdioHostChkCmdInhibitCMD(result); + if ( result ) + return result; + result = SdioHostChkDataLineActive(0); + if ( result ) + return result; + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT)((*(u8 *)&Cmd.CmdFmt & 0xF4 | 0x3A) & 0x3F); + v10 = *((u8 *)&Cmd.CmdFmt + 1); + *(u8 *)(v5 + 128) = 0; + *(u8 *)(v5 + 129) = 0; + *((u8 *)&Cmd.CmdFmt + 1) = v10 & 0xC0 | 0x18; + Cmd.Arg = v4; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete((void *)v5, v11); + if ( result ) + goto LABEL_26; + SdioHostGetResponse((void *)v5, *(u8 *)&Cmd.CmdFmt & 3); + if ( *(u32 *)(v5 + 20) & 0x4000000 ) + { +LABEL_14: + if ( ConfigDebugErr & 0x400 ) + DiagPrintf("\r[SDIO Err]Write protect violation !!\n"); + return 3; + } + result = SdioHostChkXferComplete((void *)v5, 0x1388u, v12); + if ( !result ) + return result; + if ( result != 16 ) + { + if ( v40058032 & 0x200 ) + { + v40058032 = 512; + if ( HalSdioHostStopTransferRtl8195a((void *)v5, v13) ) + { + if ( ConfigDebugErr & 0x400 ) + DiagPrintf("\r[SDIO Err]Stop transmission error!\n"); + } + } + return 238; + } + } + result = SdioHostChkCmdInhibitCMD(result); + if ( result ) + return result; + result = SdioHostChkDataLineActive(0); + if ( result ) + return result; + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT)((*(u8 *)&Cmd.CmdFmt & 0xF4 | 0x3A) & 0x3F); + v7 = *((u8 *)&Cmd.CmdFmt + 1); + *(u8 *)(v5 + 128) = 0; + *(u8 *)(v5 + 129) = 0; + *(u8 *)(v5 + 130) = 0; + *((u8 *)&Cmd.CmdFmt + 1) = v7 & 0xC0 | 0x19; + Cmd.Arg = v4; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete((void *)v5, v8); + if ( !result ) + { + SdioHostGetResponse((void *)v5, *(u8 *)&Cmd.CmdFmt & 3); + if ( *(u32 *)(v5 + 20) & 0x4000000 ) + goto LABEL_14; + result = SdioHostChkXferComplete((void *)v5, 0x1F40u, v9); + if ( !result ) + break; + } +LABEL_26: + if ( result != 16 ) + return result; + } + if ( v40058032 & 0x20 ) + return 238; + if ( v40058032 & 0x10 ) + result = 2; + else + result = 0; + return result; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (00000D34) -------------------------------------------------------- +int SdioHostSwitchFunction(void *Data, int Mode, int Fn2Sel, int Fn1Sel, uint8_t *StatusBuf) +{ + u8 *v5; // r4@1 + uint32_t v6; // r0@1 + int v7; // r5@1 + int v8; // r6@1 + char v9; // r7@3 + int result; // r0@3 + char v11; // r3@5 + uint32_t v12; // r1@5 + signed int v13; // r2@6 + uint32_t v14; // r1@6 + SDIO_HOST_CMD Cmd; // [sp+0h] [bp-20h]@1 + int v16; // [sp+8h] [bp-18h]@1 + + *(u32 *)&Cmd.CmdFmt = Data; + Cmd.Arg = Mode; + v16 = Fn2Sel; + v5 = Data; + v6 = *((u32 *)Data + 4); + v7 = Mode; + v8 = Fn2Sel; + if ( !v6 || ((u8)Fn1Sel | (u8)v6) & 3 ) + { + result = 3; + } + else + { + v40058058 = v6; + v40058004 = 64; + v4005800C = 17; + v9 = *(u8 *)v6; + *(u16 *)(v6 + 2) = 64; + *(u8 *)v6 = ((v9 | 3) & 0xFB | 4 * ((Fn1Sel | v6) & 1)) & 0xEF | 16 * ((Fn1Sel | v6) & 1) | 0x20; + *(u32 *)(v6 + 4) = Fn1Sel; + result = SdioHostChkCmdInhibitCMD(v6); + if ( !result ) + { + result = SdioHostChkDataLineActive(0); + if ( !result ) + { + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT)((*(u8 *)&Cmd.CmdFmt & 0xF4 | 0x3A) & 0x3F); + v11 = *((u8 *)&Cmd.CmdFmt + 1); + v5[128] = 0; + *((u8 *)&Cmd.CmdFmt + 1) = v11 & 0xC0 | 6; + v5[129] = 0; + Cmd.Arg = v8 | 0xFFFFF0 | (v7 << 31); + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete(v5, v12); + if ( !result ) + { + SdioHostGetResponse(v5, *(u8 *)&Cmd.CmdFmt & 3); + result = SdioHostChkXferComplete(v5, 0x1388u, v13); + if ( result ) + { + if ( result != 16 ) + { + if ( v40058032 & 0x200 ) + { + v40058032 = 512; + if ( HalSdioHostStopTransferRtl8195a(v5, v14) ) + { + DBG_SDIO_ERR("Stop transmission error!\n"); + } + } + } + result = 238; + } + } + } + } + } + return result; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (00000E34) -------------------------------------------------------- +HAL_Status HalSdioHostGetCardStatusRtl8195a(IN VOID *Data) +{ + void *v3; // r4@1 + int result; // r0@2 + char v5; // r3@3 + uint32_t v6; // r1@3 + signed int v7; // r5@3 + unsigned int v8; // r3@7 + SDIO_HOST_CMD Cmd; // [sp+0h] [bp-18h]@1 + int v10; // [sp+8h] [bp-10h]@1 + + *(u32 *)&Cmd.CmdFmt = Data; + Cmd.Arg = a2; + v10 = a3; + v3 = Data; + if ( !Data ) + return 3; + result = SdioHostChkCmdInhibitCMD((uint32_t)Data); + if ( result ) return result; + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT)((*(u8 *)&Cmd.CmdFmt & 0xF4 | 0x1A) & 0x1F); + v5 = *((u8 *)&Cmd.CmdFmt + 1); + *((u8 *)v3 + 128) = 0; + *((u8 *)&Cmd.CmdFmt + 1) = v5 & 0xC0 | 0xD; + Cmd.Arg = *((u16 *)v3 + 67) << 16; + SdioHostSendCmd(&Cmd); + v7 = SdioHostChkCmdComplete(v3, v6); + if ( v7 ) return v7; + SdioHostGetResponse(v3, *(u8 *)&Cmd.CmdFmt & 3); + if ( *((u8 *)v3 + 24) == 13 ) + { + v8 = *((u32 *)v3 + 5); + *((u32 *)v3 + 10) = v8; + *((u8 *)v3 + 131) = (v8 >> 9) & 0xF; + return v7; + } + DBG_SDIO_ERR("Command index error !!\n"); + return 238; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (00000ED0) -------------------------------------------------------- +HAL_Status HalSdioHostInitCardRtl8195a(IN VOID *Data) +{ + u8 *v3; // r5@1 + int v4; // r0@2 + char v5; // r3@3 + uint32_t v6; // r1@3 + signed int v7; // r4@4 + const char *v8; // r0@6 + int v9; // r0@7 + uint32_t v10; // r1@8 + const char *v11; // r0@11 + int v12; // r3@12 + int v13; // r0@24 + char v14; // r3@25 + uint32_t v15; // r1@25 + signed int v16; // r0@26 + const char *v17; // r0@28 + char v18; // r3@34 + uint32_t v19; // r1@34 + signed int v20; // r0@35 + signed int v21; // r6@35 + u8 v22; // cf@36 + char v23; // r3@39 + uint32_t v24; // r1@39 + signed int v25; // r0@40 + const char *v26; // r0@42 + char v27; // r3@48 + uint32_t v28; // r1@48 + const char *v29; // r0@53 + uint32_t v30; // r0@64 + int v31; // r0@64 + char v32; // r3@65 + uint32_t v33; // r1@65 + int v34; // r0@70 + char v35; // r3@71 + uint32_t v36; // r1@71 + uint32_t v37; // r1@81 + int v38; // r2@81 + int v39; // r6@81 + int v40; // r1@82 + const char *v41; // r0@83 + int v42; // r0@87 + uint32_t v43; // r1@87 + int v44; // r2@87 + int v45; // r3@88 + uint32_t v46; // r1@88 + signed int v47; // r0@89 + const char *v48; // r0@91 + char v49; // r3@98 + uint32_t v50; // r1@98 + void *v52; // [sp+0h] [bp-20h]@1 + int v53; // [sp+4h] [bp-1Ch]@1 + int v54; // [sp+8h] [bp-18h]@1 + + v52 = Data; + v53 = a2; + v54 = a3; + v3 = Data; + if ( !Data ) + { + v7 = 3; + goto LABEL_115; + } + v4 = SdioHostChkCmdInhibitCMD((uint32_t)Data); + if ( !v4 ) + { + v5 = (char)v52; + v3[128] = 0; + LOBYTE(v52) = v5 & 4; + v53 = 0; + BYTE1(v52) &= 0xC0u; + SdioHostSendCmd((SDIO_HOST_CMD *)&v52); + v4 = SdioHostChkCmdComplete(v3, v6); + } + v7 = v4; + if ( v4 ) + { + DBG_SDIO_ERR("Reset sd card fail !!\n"); + goto LABEL_104; + } + goto LABEL_115; + } + v9 = SdioHostChkCmdInhibitCMD(0); + if ( v9 + || (LOBYTE(v52) = (((u8)v52 & 0xF4 | 0x1A) & 0xDF | 32 * (v7 & 1)) & 0x3F | ((v7 & 3) << 6), + BYTE1(v52) = BYTE1(v52) & 0xC0 | 8, + v3[128] = v7, + v53 = 426, + SdioHostSendCmd((SDIO_HOST_CMD *)&v52), + (v9 = SdioHostChkCmdComplete(v3, v10)) != 0) ) + { + v7 = v9; + if ( v9 ) + goto LABEL_22; + } + else + { + SdioHostGetResponse(v3, (u8)v52 & 3); + if ( v3[24] != 8 ) + { + if ( ConfigDebugErr & 0x400 ) + { + v11 = "\r[SDIO Err]Command index error !!\n"); // DBG_SDIO_ERR(" +LABEL_18: + DiagPrintf(v11); + goto LABEL_21; + } + goto LABEL_21; + } + v12 = *((u32 *)v3 + 5); + if ( (u8)v12 != 170 ) + { + DBG_SDIO_ERR("Echo-back of check pattern: %X\n"); + goto LABEL_21; + } + v9 = v12 << 23; + if ( !(v12 & 0x100) ) + { + if ( ConfigDebugErr & 0x400 ) + { + v11 = "\r[SDIO Err]Voltage accepted error!\n"; + goto LABEL_18; + } +LABEL_21: + v7 = 238; +LABEL_22: + if ( ConfigDebugErr & 0x400 ) + { + v8 = "\r[SDIO Err]Voltage check fail !!\n"; + goto LABEL_104; + } + goto LABEL_115; + } + } + v13 = SdioHostChkCmdInhibitCMD(v9); + if ( v13 ) + goto LABEL_63; + LOBYTE(v52) = ((u8)v52 & 0xFC | 0x1A) & 0x1F; + v14 = BYTE1(v52) & 0xC0 | 0x37; + v3[128] = v7; + BYTE1(v52) = v14; + v53 = v7; + SdioHostSendCmd((SDIO_HOST_CMD *)&v52); + v13 = SdioHostChkCmdComplete(v3, v15); + if ( v13 ) + goto LABEL_63; + v16 = SdioHostGetResponse(v3, (u8)v52 & 3); + if ( v3[24] != 55 ) + { + if ( ConfigDebugErr & 0x400 ) // DBG_SDIO_ERR(" + { + v17 = "\r[SDIO Err]Command index error !!\n"; +LABEL_32: + DiagPrintf(v17); + goto LABEL_57; + } + goto LABEL_57; + } + if ( !(*((u32 *)v3 + 5) & 0x20) ) + { + if ( ConfigDebugErr & 0x400 ) + { + v17 = "\r[SDIO Err]ACMD isn't expected!\n"; + goto LABEL_32; + } +LABEL_57: + v7 = 238; + goto LABEL_60; + } + v13 = SdioHostChkCmdInhibitCMD(v16); + if ( v13 + || (LOBYTE(v52) = ((u8)v52 & 0xFC | 2) & 7, + v18 = BYTE1(v52) & 0xC0 | 0x29, + v3[128] = v7, + BYTE1(v52) = v18, + v53 = v7, + SdioHostSendCmd((SDIO_HOST_CMD *)&v52), + (v13 = SdioHostChkCmdComplete(v3, v19)) != 0) ) + { +LABEL_63: + v7 = v13; + if ( !v13 ) + goto LABEL_64; +LABEL_60: + if ( ConfigDebugErr & 0x400 ) + { + v8 = "\r[SDIO Err]Get OCR fail !!\n"; + goto LABEL_104; + } + goto LABEL_115; + } + v20 = SdioHostGetResponse(v3, (u8)v52 & 3); + v21 = 100; + *((u32 *)v3 + 9) = *((u32 *)v3 + 5) & 0xFFFFFF; + while ( 1 ) + { + v22 = __CFADD__(v21--, -1); + if ( !v22 ) + goto LABEL_51; + v13 = SdioHostChkCmdInhibitCMD(v20); + if ( v13 ) + goto LABEL_63; + LOBYTE(v52) = ((u8)v52 & 0xFC | 0x1A) & 0x1F; + v23 = BYTE1(v52); + v3[128] = 0; + v53 = 0; + BYTE1(v52) = v23 & 0xC0 | 0x37; + SdioHostSendCmd((SDIO_HOST_CMD *)&v52); + v13 = SdioHostChkCmdComplete(v3, v24); + if ( v13 ) + goto LABEL_63; + v25 = SdioHostGetResponse(v3, (u8)v52 & 3); + if ( v3[24] != 55 ) + { + if ( ConfigDebugErr & 0x400 ) + { + v26 = "\r[SDIO Err]Command index error !!\n"; +LABEL_46: + DiagPrintf(v26); + goto LABEL_62; + } + goto LABEL_62; + } + if ( !(*((u32 *)v3 + 5) & 0x20) ) + { + if ( ConfigDebugErr & 0x400 ) + { + v26 = "\r[SDIO Err]ACMD isn't expected!\n"; + goto LABEL_46; + } +LABEL_62: + v13 = 238; + goto LABEL_63; + } + v13 = SdioHostChkCmdInhibitCMD(v25); + if ( v13 ) + goto LABEL_63; + LOBYTE(v52) = ((u8)v52 & 0xFC | 2) & 7; + v27 = BYTE1(v52); + v3[128] = 0; + BYTE1(v52) = v27 & 0xC0 | 0x29; + v53 = 1077673984; + SdioHostSendCmd((SDIO_HOST_CMD *)&v52); + v13 = SdioHostChkCmdComplete(v3, v28); + if ( v13 ) + goto LABEL_63; + SdioHostGetResponse(v3, (u8)v52 & 3); + if ( *((u32 *)v3 + 5) < 0 ) + break; + v20 = HalDelayUs(10000); + } + if ( !v21 ) + { + v7 = 2; + goto LABEL_60; + } +LABEL_51: + if ( *((u32 *)v3 + 5) & 0x40000000 ) + { + v3[132] = 1; + if ( !(ConfigDebugInfo & 0x400) ) + goto LABEL_64; + v29 = "\r[SDIO Inf]This is a SDHC card\n"; + } + else + { + v3[132] = 0; + if ( !(ConfigDebugInfo & 0x400) ) + goto LABEL_64; + v29 = "\r[SDIO Inf]This is a SDSC card\n"; + } + DiagPrintf(v29); +LABEL_64: + v30 = HalDelayUs(20); + v31 = SdioHostChkCmdInhibitCMD(v30); + if ( v31 + || (LOBYTE(v52) = ((u8)v52 & 0xF4 | 9) & 0xF, + v32 = BYTE1(v52) & 0xC0 | 2, + v3[128] = v7, + BYTE1(v52) = v32, + v53 = v7, + SdioHostSendCmd((SDIO_HOST_CMD *)&v52), + (v31 = SdioHostChkCmdComplete(v3, v33)) != 0) ) + { + v7 = v31; + if ( !v31 ) + goto LABEL_70; + if ( ConfigDebugErr & 0x400 ) + { + v8 = "\r[SDIO Err]Get CID fail !!\n"; + goto LABEL_104; + } + goto LABEL_115; + } + v31 = SdioHostGetResponse(v3, (u8)v52 & 3); +LABEL_70: + v34 = SdioHostChkCmdInhibitCMD(v31); + if ( v34 + || (LOBYTE(v52) = ((u8)v52 & 0xF4 | 0x1A) & 0x1F, + v35 = BYTE1(v52) & 0xC0 | 3, + v3[128] = v7, + BYTE1(v52) = v35, + v53 = v7, + SdioHostSendCmd((SDIO_HOST_CMD *)&v52), + (v34 = SdioHostChkCmdComplete(v3, v36)) != 0) ) + { + v7 = v34; + if ( v34 ) + goto LABEL_79; + } + else + { + SdioHostGetResponse(v3, (u8)v52 & 3); + if ( v3[24] != 3 ) + { + if ( ConfigDebugErr & 0x400 ) + DiagPrintf("\r[SDIO Err]Command index error !!\n"); + v7 = 238; +LABEL_79: + if ( ConfigDebugErr & 0x400 ) + { + v8 = "\r[SDIO Err]Get RCA fail !!\n"; + goto LABEL_104; + } + goto LABEL_115; + } + *((u16 *)v3 + 67) = *((u16 *)v3 + 11); + } + SdioHostSdClkCtrl(v3, 1, 1); + v39 = SdioHostGetCSD(v3, v37); + if ( v39 ) + { + v40 = ConfigDebugErr << 21; + if ( ConfigDebugErr & 0x400 ) + { + v41 = "\r[SDIO Err]Get CSD fail !!\n"; + goto LABEL_108; + } +LABEL_113: + v7 = v39; + goto LABEL_115; + } + v39 = SdioHostCardSelection(v3, 1, v38); + if ( v39 ) + { + if ( !(ConfigDebugErr & 0x400) ) + goto LABEL_113; + v41 = "\r[SDIO Err]Select sd card fail !!\n"; +LABEL_108: + DiagPrintf(v41, v40); + goto LABEL_113; + } + v42 = SdioHostChkCmdInhibitCMD(0); + if ( v42 ) + goto LABEL_120; + LOBYTE(v52) = ((u8)v52 & 0xFC | 0x1A) & 0x1F; + BYTE1(v52) = BYTE1(v52) & 0xC0 | 0x37; + v45 = *((u16 *)v3 + 67) << 16; + v3[128] = v7; + v53 = v45; + SdioHostSendCmd((SDIO_HOST_CMD *)&v52); + v42 = SdioHostChkCmdComplete(v3, v46); + if ( v42 ) + goto LABEL_120; + v47 = SdioHostGetResponse(v3, (u8)v52 & 3); + if ( v3[24] != 55 ) + goto LABEL_90; + if ( !(*((u32 *)v3 + 5) & 0x20) ) + { + if ( ConfigDebugErr & 0x400 ) + { + v48 = "\r[SDIO Err]ACMD isn't expected!\n"; +LABEL_95: + DiagPrintf(v48); + } + goto LABEL_96; + } + v42 = SdioHostChkCmdInhibitCMD(v47); + if ( v42 + || (LOBYTE(v52) = ((u8)v52 & 0xFC | 0x1A) & 0x1F, + v49 = BYTE1(v52) & 0xC0 | 6, + v3[128] = v7, + BYTE1(v52) = v49, + v53 = 2, + SdioHostSendCmd((SDIO_HOST_CMD *)&v52), + (v42 = SdioHostChkCmdComplete(v3, v50)) != 0) ) + { +LABEL_120: + v7 = v42; + if ( v42 ) + goto LABEL_102; +LABEL_105: + v39 = HalSdioHostGetCardStatusRtl8195a(v3, v43, v44); + if ( v39 ) + { + v40 = ConfigDebugErr << 21; + if ( !(ConfigDebugErr & 0x400) ) + goto LABEL_113; + v41 = "\r[SDIO Err]Get sd card current state fail !!\n"; + goto LABEL_108; + } + if ( v3[131] != 4 ) + { + DBG_SDIO_ERR("The card isn't in TRANSFER state !! (Current state: %d)\n", + v3[131], + ConfigDebugErr << 21); + v7 = 238; + goto LABEL_115; + } + } + else + { + SdioHostGetResponse(v3, (u8)v52 & 3); + if ( v3[24] == 6 ) + { + v44 = v40058028 | 2; + v40058028 |= 2u; + goto LABEL_105; + } +LABEL_90: + if ( ConfigDebugErr & 0x400 ) + { + v48 = "\r[SDIO Err]Command index error !!\n"; + goto LABEL_95; + } +LABEL_96: + v7 = 238; +LABEL_102: + if ( ConfigDebugErr & 0x400 ) + { + v8 = "\r[SDIO Err]Set bus width fail !!\n"; +LABEL_104: + DiagPrintf(v8); + } +LABEL_115: + DBG_SDIO_ERR"SD card initialization FAIL !!\n"); + } + return v7; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); +// 23F0: using guessed type int HalDelayUs(u32); + +//----- (000014E8) -------------------------------------------------------- +HAL_Status HalSdioHostGetSdStatusRtl8195a(IN VOID *Data) +{ + int v3; // r3@1 + char *v4; // r4@1 + char v5; // r0@3 + int v6; // r0@3 + int result; // r0@3 + int v8; // r3@4 + uint32_t v9; // r1@4 + const char *v10; // r0@7 + int v11; // r3@8 + char v12; // r3@13 + uint32_t v13; // r1@13 + signed int v14; // r2@14 + signed int v15; // r0@14 + uint32_t v16; // r1@14 + SDIO_HOST_CMD Cmd; // [sp+0h] [bp-18h]@1 + int v18; // [sp+8h] [bp-10h]@1 + + v3 = *((u32 *)Data + 4); + *(u32 *)&Cmd.CmdFmt = Data; + Cmd.Arg = a2; + v18 = a3; + v4 = (char *)Data; + if ( !v3 || v3 & 3 ) + { + result = 3; + } + else + { + v40058058 = v3; + v40058004 = 64; + v4005800C = 17; + v5 = *(u8 *)v3; + *(u16 *)(v3 + 2) = 64; + v6 = (u8)((v5 | 3) & 0xEB) | 0x20; + *(u8 *)v3 = v6; + *(u32 *)(v3 + 4) = v4 + 48; + result = SdioHostChkCmdInhibitCMD(v6); + if ( !result ) + { + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT)((*(u8 *)&Cmd.CmdFmt & 0xFC | 0x1A) & 0x1F); + *((u8 *)&Cmd.CmdFmt + 1) = *((u8 *)&Cmd.CmdFmt + 1) & 0xC0 | 0x37; + v8 = *((u16 *)v4 + 67); + v4[128] = 0; + Cmd.Arg = v8 << 16; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete(v4, v9); + if ( !result ) + { + SdioHostGetResponse(v4, *(u8 *)&Cmd.CmdFmt & 3); + if ( v4[24] != 55 ) + { + if ( ConfigDebugErr & 0x400 ) + { + v10 = "\r[SDIO Err]Command index error !!\n"; +LABEL_20: + DiagPrintf(v10); + return 238; + } + return 238; + } + v11 = *((u32 *)v4 + 5); + if ( !(v11 & 0x20) ) + { + if ( ConfigDebugErr & 0x400 ) + { + v10 = "\r[SDIO Err]ACMD isn't expected!\n"; + goto LABEL_20; + } + return 238; + } + result = SdioHostChkCmdInhibitCMD(*((u32 *)v4 + 5) << 26); + if ( !result ) + { + result = SdioHostChkDataLineActive(0); + if ( !result ) + { + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT)((*(u8 *)&Cmd.CmdFmt & 0xFC | 0x3A) & 0x3F); + v12 = *((u8 *)&Cmd.CmdFmt + 1); + v4[128] = 0; + v4[129] = 0; + Cmd.Arg = 0; + *((u8 *)&Cmd.CmdFmt + 1) = v12 & 0xC0 | 0xD; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete(v4, v13); + if ( !result ) + { + SdioHostGetResponse(v4, *(u8 *)&Cmd.CmdFmt & 3); + v15 = SdioHostChkXferComplete(v4, 0x1388u, v14); + if ( v15 ) + { + if ( v15 == 16 ) + return 238; + if ( !(v40058032 & 0x200) ) + return 238; + v40058032 = 512; + if ( !HalSdioHostStopTransferRtl8195a(v4, v16) || !(ConfigDebugErr & 0x400) ) + return 238; + v10 = "\r[SDIO Err]Stop transmission error!\n"; + goto LABEL_20; + } + result = 0; + } + } + } + } + } + } + return result; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (00001668) -------------------------------------------------------- +HAL_Status HalSdioHostChangeSdClockRtl8195a(IN VOID *Data, IN u8 Frequency) +{ + u8 *v2; // r5@1 + int v3; // r4@6 + int v4; // r2@8 + int v5; // r0@10 + int v6; // r0@10 + char v7; // r3@11 + uint32_t v8; // r1@11 + signed int v9; // r0@12 + const char *v10; // r0@14 + char v11; // r3@22 + uint32_t v12; // r1@22 + signed int v13; // r2@23 + signed int v14; // r0@23 + uint32_t v15; // r1@25 + int v16; // r0@32 + int v17; // r0@34 + int v18; // r0@36 + const char *v19; // r0@40 + int v20; // r2@52 + char v22; // [sp+0h] [bp-58h]@11 + char v23; // [sp+1h] [bp-57h]@11 + int v24; // [sp+4h] [bp-54h]@11 + uint8_t StatusData[64]; // [sp+8h] [bp-50h]@8 + + v2 = Data; + if ( !Data || (unsigned int)(Frequency - 5) > 3 ) + return 3; + if ( *((u8 *)Data + 133) == Frequency ) + { + DBG_SDIO_WARN("Current SDCLK frequency is already the specified value...\n"); + return 0; + } + if ( Frequency != 8 ) + { + if ( Frequency == 6 ) + { + v20 = 2; + } + else if ( Frequency == 7 ) + { + v20 = 1; + } + else + { + if ( Frequency != 5 ) + { + DBG_SDIO_ERR("Unsupported SDCLK frequency !!\n"); + v3 = 3; + goto LABEL_60; + } + v20 = 4; + } + v3 = SdioHostSdClkCtrl(Data, 1, v20); + if ( !v3 ) + return 0; +LABEL_60: + if ( !(ConfigDebugErr & 0x400) ) + return v3; + v19 = "\r[SDIO Err]Host changes clock fail !!\n"; // DBG_SDIO_ERR(" + goto LABEL_62; + } + v4 = *((u32 *)Data + 4); + *(u32 *)StatusData = 0; + *(u32 *)&StatusData[4] = 0; + if ( !v4 || v4 & 3 ) + return 3; + v40058058 = v4; + v40058004 = 8; + v4005800C = 17; + v5 = (u8)((*(u8 *)v4 | 3) & 0xEB) | 0x20; + *(u8 *)v4 = v5; + *(u16 *)(v4 + 2) = 8; + *(u32 *)(v4 + 4) = StatusData; + v6 = SdioHostChkCmdInhibitCMD(v5); + if ( v6 ) + goto LABEL_70; + v22 = (v22 & 0xF4 | 0x1A) & 0x1F; + v7 = v23; + v2[128] = 0; + v23 = v7 & 0xC0 | 0x37; + v24 = *((u16 *)v2 + 67) << 16; + SdioHostSendCmd((SDIO_HOST_CMD *)&v22); + v6 = SdioHostChkCmdComplete(v2, v8); + if ( v6 ) + goto LABEL_70; + v9 = SdioHostGetResponse(v2, v22 & 3); + if ( v2[24] != 55 ) + { + if ( !(ConfigDebugErr & 0x400) ) + return 238; + v10 = "\r[SDIO Err]Command index error !!\n"; +LABEL_15: + DiagPrintf(v10); + return 238; + } + if ( !(*((u32 *)v2 + 5) & 0x20) ) + { + if ( !(ConfigDebugErr & 0x400) ) + return 238; + v10 = "\r[SDIO Err]ACMD isn't expected!\n"; + goto LABEL_15; + } + v6 = SdioHostChkCmdInhibitCMD(v9); + if ( v6 + || (v6 = SdioHostChkDataLineActive(0)) != 0 + || (v22 = (v22 & 0xF4 | 0x3A) & 0x3F, + v11 = v23, + v2[128] = 0, + v2[129] = 0, + v24 = 0, + v23 = v11 & 0xC0 | 0x33, + SdioHostSendCmd((SDIO_HOST_CMD *)&v22), + (v6 = SdioHostChkCmdComplete(v2, v12)) != 0) ) + { +LABEL_70: + v3 = v6; + if ( v6 ) + return v3; + } + else + { + SdioHostGetResponse(v2, v22 & 3); + v14 = SdioHostChkXferComplete(v2, 0x1388u, v13); + if ( v14 ) + { + if ( v14 == 16 ) + return 238; + v15 = v40058032 << 22; + if ( !(v40058032 & 0x200) ) + return 238; + v40058032 = 512; + if ( !HalSdioHostStopTransferRtl8195a(v2, v15) || !(ConfigDebugErr & 0x400) ) + return 238; + v10 = "\r[SDIO Err]Stop transmission error!\n"; + goto LABEL_15; + } + v3 = 0; + *((u16 *)v2 + 68) = StatusData[0] & 0xF; + } + if ( *((u16 *)v2 + 68) ) + { + v16 = SdioHostSwitchFunction(v2, 0, 15, (int)StatusData, *(uint8_t **)&v22); + if ( v16 ) + return v16; + if ( StatusData[13] & 2 ) + { + v17 = SdioHostSwitchFunction(v2, v16, 1, (int)StatusData, *(uint8_t **)&v22); + if ( v17 ) + return v17; + if ( (StatusData[16] & 0xF) != 1 ) + { + if ( !(ConfigDebugErr & 0x400) ) + return 238; + v10 = "\r[SDIO Err]\"High-Speed\" can't be switched !!\n"; + goto LABEL_15; + } + v18 = SdioHostSwitchFunction(v2, 1, 1, (int)StatusData, *(uint8_t **)&v22); + if ( v18 ) + return v18; + if ( (StatusData[16] & 0xF) != 1 ) + { + if ( !(ConfigDebugErr & 0x400) ) + return 238; + v10 = "\r[SDIO Err]Card changes to High-Speed fail !!\n"; + goto LABEL_15; + } + v3 = SdioHostSdClkCtrl(v2, 1, v18); + if ( v3 ) + { + if ( !(ConfigDebugErr & 0x400) ) + return v3; + v19 = "\r[SDIO Err]Host changes to High-Speed fail !!\n"; +LABEL_62: + DiagPrintf(v19); + return v3; + } + } + else if ( ConfigDebugInfo & 0x400 ) + { + // DBG_SDIO_WARN(" + v19 = "\r[SDIO Inf]This card doesn't support \"High-Speed Function\" and can't change to high-speed...\n"; + goto LABEL_62; + } + } + else if ( ConfigDebugInfo & 0x400 ) + { + v19 = "\r[SDIO Inf]This card doesn't support CMD6 and can't change to high-speed...\n"; + goto LABEL_62; + } + return 0; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (0000194C) -------------------------------------------------------- +HAL_Status HalSdioHostEraseRtl8195a(IN VOID *Data, IN u64 StartAddr, IN u64 EndAddr) +{ + uint32_t v3; // r4@1 + uint32_t v4; // r6@1 + int v5; // r8@1 + int result; // r0@4 + char v7; // r3@5 + uint32_t v8; // r1@5 + signed int v9; // r0@6 + char v10; // r3@11 + uint32_t v11; // r1@11 + signed int v12; // r0@12 + char v13; // r3@15 + uint32_t v14; // r1@15 + signed int v15; // r2@15 + SDIO_HOST_CMD v16; // [sp+0h] [bp-20h]@1 + + v16 = (SDIO_HOST_CMD)EndAddr; + v3 = EndAddra; + v4 = a2; + v5 = EndAddr; + if ( !(u32)EndAddr ) + return 3; + if ( *(u8 *)(EndAddr + 132) ) + { + v4 = a2 >> 9; + v3 = EndAddra >> 9; + } + result = SdioHostChkCmdInhibitCMD(EndAddr); + if ( !result ) + { + v16.CmdFmt = (SDIO_HOST_CMD_FMT)((*(u8 *)&v16.CmdFmt & 0xFC | 0x1A) & 0x1F); + v7 = *((u8 *)&v16.CmdFmt + 1); + *(u8 *)(v5 + 128) = 0; + *((u8 *)&v16.CmdFmt + 1) = v7 & 0xC0 | 0x20; + v16.Arg = v4; + SdioHostSendCmd(&v16); + result = SdioHostChkCmdComplete((void *)v5, v8); + if ( !result ) + { + v9 = SdioHostGetResponse((void *)v5, *(u8 *)&v16.CmdFmt & 3); + if ( *(u8 *)(v5 + 24) != 32 ) + goto LABEL_20; + result = SdioHostChkCmdInhibitCMD(v9); + if ( result ) + return result; + v16.CmdFmt = (SDIO_HOST_CMD_FMT)((*(u8 *)&v16.CmdFmt & 0xFC | 0x1A) & 0x1F); + v10 = *((u8 *)&v16.CmdFmt + 1); + *(u8 *)(v5 + 128) = 0; + *((u8 *)&v16.CmdFmt + 1) = v10 & 0xC0 | 0x21; + v16.Arg = v3; + SdioHostSendCmd(&v16); + result = SdioHostChkCmdComplete((void *)v5, v11); + if ( result ) + return result; + v12 = SdioHostGetResponse((void *)v5, *(u8 *)&v16.CmdFmt & 3); + if ( *(u8 *)(v5 + 24) != 33 ) + { +LABEL_20: + DBG_SDIO_ERR("Command index error !!\n"); + result = 238; + } + else + { + result = SdioHostChkCmdInhibitCMD(v12); + if ( !result ) + { + result = SdioHostChkCmdInhibitDAT(0); + if ( !result ) + { + v16.CmdFmt = (SDIO_HOST_CMD_FMT)((*(u8 *)&v16.CmdFmt | 0x1B) & 0x1F); + v13 = *((u8 *)&v16.CmdFmt + 1); + *(u8 *)(v5 + 128) = 0; + *(u8 *)(v5 + 129) = 0; + v16.Arg = 0; + *((u8 *)&v16.CmdFmt + 1) = v13 & 0xC0 | 0x26; + SdioHostSendCmd(&v16); + result = SdioHostChkCmdComplete((void *)v5, v14); + if ( !result ) + result = SdioHostChkXferComplete((void *)v5, 0x1388u, v15); + } + } + } + } + } + return result; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (00001AA8) -------------------------------------------------------- +HAL_Status HalSdioHostGetWriteProtectRtl8195a(IN VOID *Data); +{ + void *v3; // r4@1 + uint32_t v4; // r1@2 + int v5; // r2@2 + int v6; // r5@2 + signed int result; // r0@6 + int v8; // r2@10 + const char *v9; // r0@13 + + v3 = Data; + if ( !Data ) + return 3; + v6 = HalSdioHostGetCardStatusRtl8195a(Data, a2, a3); + if ( v6 ) + { + if ( !(ConfigDebugErr & 0x400) ) + return v6; + v9 = "\r[SDIO Err]Get card status fail !!\n"; +LABEL_16: + DiagPrintf(v9); + return v6; + } + if ( *((u8 *)v3 + 131) == 3 ) + { +LABEL_10: + v6 = SdioHostGetCSD(v3, v4); + if ( !v6 ) + { + *((u32 *)v3 + 11) = ((unsigned int)*((u8 *)v3 + 126) >> 4) & 1; + return SdioHostCardSelection(v3, 1, v8); + } + if ( !(ConfigDebugErr & 0x400) ) + return v6; + v9 = "\r[SDIO Err]Get CSD fail !!\n"; + goto LABEL_16; + } + if ( *((u8 *)v3 + 131) == 4 || *((u8 *)v3 + 131) == 5 ) + { + result = SdioHostCardSelection(v3, 0, v5); + if ( result ) + return result; + goto LABEL_10; + } + if ( ConfigDebugErr & 0x400 ) + DiagPrintf("\r[SDIO Err]Wrong card state !!\n", ConfigDebugErr << 21); + return 238; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (00001B48) -------------------------------------------------------- +HAL_Status HalSdioHostSetWriteProtectRtl8195a(IN VOID *Data, IN u8 Setting) +{ + int v2; // r3@1 + u8 *v3; // r4@1 + int v4; // r2@2 + uint8_t v5; // r2@5 + int v6; // r1@7 + unsigned int v7; // r2@7 + signed int v8; // r0@8 + u8 v9; // cf@11 + char v10; // r1@13 + int result; // r0@13 + char v12; // r3@15 + uint32_t v13; // r1@15 + signed int v14; // r2@16 + uint32_t v15; // r1@20 + char v16; // [sp+0h] [bp-30h]@15 + char v17; // [sp+1h] [bp-2Fh]@15 + HAL_Status ret; // [sp+4h] [bp-2Ch]@15 + uint8_t tmp[16]; // [sp+8h] [bp-28h]@3 + + v2 = *((u32 *)Data + 4); + v3 = Data; + if ( !v2 ) + return 3; + v4 = *((u32 *)Data + 4) & 3; + if ( v2 & 3 ) + return 3; + do + { + tmp[v4] = *((u8 *)Data + v4 + 112); + ++v4; + } + while ( v4 != 15 ); + if ( Setting == 1 ) + v5 = tmp[14] | 0x10; + else + v5 = tmp[14] & 0xEF; + v6 = 0; + tmp[14] = v5; + LOBYTE(v7) = 0; + do + { + v8 = 7; + do + { + v7 = (u8)(2 * v7); + if ( (((signed int)tmp[v6] >> v8) & 1) != v7 >> 7 ) + LOBYTE(v7) = v7 ^ 0x89; + v9 = __CFADD__(v8--, -1); + } + while ( v9 ); + ++v6; + } + while ( v6 != 15 ); + tmp[15] = 2 * v7 | 1; + v40058058 = v2; + v40058004 = 16; + v4005800C = 1; + v10 = *(u8 *)v2; + *(u16 *)(v2 + 2) = 16; + *(u8 *)v2 = v10 & 0xC8 | 0x23; + *(u32 *)(v2 + 4) = tmp; + result = SdioHostChkCmdInhibitCMD(1u); + if ( !result ) + { + result = SdioHostChkDataLineActive(0); + if ( !result ) + { + v16 = (v16 & 0xF4 | 0x3A) & 0x3F; + v12 = v17; + v3[128] = 0; + v3[129] = 0; + ret = 0; + v17 = v12 & 0xC0 | 0x1B; + SdioHostSendCmd((SDIO_HOST_CMD *)&v16); + result = SdioHostChkCmdComplete(v3, v13); + if ( !result ) + { + SdioHostGetResponse(v3, v16 & 3); + if ( *((u32 *)v3 + 5) & 0x4000000 ) + { + DBG_SDIO_ERR("Write protect violation !!\n", ConfigDebugErr << 21); + return 3; + } + result = SdioHostChkXferComplete(v3, 0x1388u, v14); + if ( result ) + { + if ( result != 16 ) + { + if ( v40058032 & 0x200 ) + { + v40058032 = 512; + if ( HalSdioHostStopTransferRtl8195a(v3, v15) ) + { + DBG_SDIO_ERR("Stop transmission error!\n"); + } + } + } + result = 238; + } + } + } + } + return result; +} + + diff --git a/RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a_usb.h b/RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a_usb.h new file mode 100644 index 0000000..2543e79 --- /dev/null +++ b/RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a_usb.h @@ -0,0 +1,111 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _RTL8195A_USB_H_ +#define _RTL8195A_USB_H_ + + +// common command for USB +#define USB_CMD_TX_ETH 0x83 // request to TX a 802.3 packet +#define USB_CMD_TX_WLN 0x81 // request to TX a 802.11 packet +#define USB_CMD_H2C 0x11 // H2C(host to device) command packet +#define USB_CMD_MEMRD 0x51 // request to read a block of memory data +#define USB_CMD_MEMWR 0x53 // request to write a block of memory +#define USB_CMD_MEMST 0x55 // request to set a block of memory with a value +#define USB_CMD_STARTUP 0x61 // request to jump to the start up function + +#define USB_CMD_RX_ETH 0x82 // indicate a RX 802.3 packet +#define USB_CMD_RX_WLN 0x80 // indicate a RX 802.11 packet +#define USB_CMD_C2H 0x10 // C2H(device to host) command packet +#define USB_CMD_MEMRD_RSP 0x50 // response to memory block read command +#define USB_CMD_MEMWR_RSP 0x52 // response to memory write command +#define USB_CMD_MEMST_RSP 0x54 // response to memory set command +#define USB_CMD_STARTED 0x60 // indicate the program has jumped to the given function + + +// TODO: This data structer just for test, we should modify it for the normal driver +typedef struct _USB_TX_DESC{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 txpktsize:16; // bit[15:0] + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number +#else + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 txpktsize:16; // bit[15:0] +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the packet type + u32 rsvd0:24; +#else + u32 rsvd0:24; + u32 type:8; // bit[7:0], the packet type +#endif + + // u4Byte 2 + u32 rsvd1; + + // u4Byte 3 + u32 rsvd2; + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} USB_TX_DESC, *PUSB_TX_DESC; + +#define SIZE_USB_TX_DESC sizeof(USB_TX_DESC) + +// TODO: This data structer just for test, we should modify it for the normal driver +typedef struct _USB_RX_DESC{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 pkt_len:16; // bit[15:0], the packet size + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 rsvd0:6; // bit[29:24] + u32 icv:1; // bit[30], ICV error + u32 crc:1; // bit[31], CRC error +#else + u32 crc:1; // bit[31], CRC error + u32 icv:1; // bit[30], ICV error + u32 rsvd0:6; // bit[29:24] + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 pkt_len:16; // bit[15:0], the packet size +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the type of this packet + u32 rsvd1:24; // bit[31:8] +#else + u32 rsvd1:24; // bit[31:8] + u32 type:8; // bit[7:0], the type of this packet +#endif + + // u4Byte 2 + u32 rsvd2; + + // u4Byte 3 + u32 rsvd3; + + // u4Byte 4 + u32 rsvd4; + + // u4Byte 5 + u32 rsvd5; +} USB_RX_DESC, *PUSB_RX_DESC; + +#define SIZE_USB_RX_DESC sizeof(USB_RX_DESC) + +#endif // #ifndef _RTL8195A_USB_H_ + diff --git a/RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/src/Descript.ion b/RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/src/Descript.ion index 86c04c0..2af2828 100644 --- a/RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/src/Descript.ion +++ b/RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/src/Descript.ion @@ -4,4 +4,4 @@ hal_misc.c + hal_pinmux.c + hal_sdio_host.c + hal_soc_ps_monitor.c + -hal_spi_flash_ram.c +- +hal_spi_flash_ram.c + diff --git a/RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/src/hal_spi_flash_ram.c b/RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/src/hal_spi_flash_ram.c index f5bb039..a1871f0 100644 --- a/RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/src/hal_spi_flash_ram.c +++ b/RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/src/hal_spi_flash_ram.c @@ -1,1252 +1,1468 @@ /* - * hal_spi_flash_ram.c - * reversed hal_spi_flash_ram.o pvvx 17/10/16 ... - * 'Revers' is not finished, not tested, not to include in the project! + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. */ - #include "rtl8195a.h" +#include "hal_spi_flash.h" -//------------------------------------------------------------------------- -// Function declarations -//extern VOID SpicLoadInitParaFromClockRtl8195A (IN u8 CpuClkMode, IN u8 BaudRate, IN PSPIC_INIT_PARA pSpicInitPara); -//------------------------------------------------------------------------- -// Data declarations -//char algn_1[]; // weak -//int unk_2; // weak +#include "rtl8195a_spi_flash.h" -typedef struct _SPIC_INIT_PARA_ROM_ { - u8 BaudRate; - u8 RdDummyCyle; - u8 DelayLine; - u8 Rsvd; -}SPIC_INIT_PARA_ROM, *PSPIC_INIT_PARA_ROM; -SPIC_INIT_PARA HAL_FLASH_DATA_SECTION SpicInitParaAllClk[3][6]; // SpicInitParaAllClk[SPIC_BIT_MODE][CPU_CK_SEL] +#define SPI_CTRL_BASE 0x1FFEF000 +#define SPI_DLY_CTRL_ADDR 0x40000300 // [7:0] +#define MIN_BAUDRATE 0x01 +#define MAX_BAUDRATE 0x04 +#define MAX_AUTOLEN 0x14 +#define MAX_DLYLINE 99 +#define GOLD_ID_NO_RAM 0xC220 -#ifdef INCLUDE_ROM_FUNCTIONS +#define WR_DATA(addr, data) (*((volatile u32*)(addr)) = (data)) +#define RD_DATA(addr) (*((volatile u32*)(addr))) -extern SPIC_INIT_PARA_ROM SpicInitCPUCLK[3]; // ROM: 0x30c98; +BOOLEAN SpicFlashInitRtl8195A( u8 SpicBitMode ); +u32 SpicCalibrationRtl8195A( u8 SpicBitMode, u32 DefRdDummyCycle ); // spi-flash calibration -SPIC_INIT_PARA_ROM SpicInitCPUCLK[4] = { - { 0x01, 0x01, 0x5E, 0x00 }, - { 0x01, 0x01, 0x00, 0x00 }, - { 0x01, 0x02, 0x23, 0x00 }, - { 0x01, 0x05, 0x05, 0x00 } +VOID SpicSetFlashStatusRefinedRtl8195A( u32 data, SPIC_INIT_PARA SpicInitPara ); + +VOID SpicConfigAutoModeRtl8195A( u8 SpicBitMode ); // config spi-flash controller to auto mode +VOID SpicReadIDRtl8195A( VOID ); + + +_LONG_CALL_ +extern VOID SpicInitRtl8195A( u8 InitBaudRate, + u8 SpicBitMode ); // spi-flash controller initialization + +_LONG_CALL_ +extern VOID SpicRxCmdRtl8195A( u8 ); // recieve command + +_LONG_CALL_ +extern VOID SpicSetFlashStatusRtl8195A( u32 data, + SPIC_INIT_PARA SpicInitPara ); // WRSR, write spi-flash status register + +_LONG_CALL_ +extern VOID SpicWaitBusyDoneRtl8195A( VOID ); // wait sr[0] = 0, wait transmission done + +_LONG_CALL_ +extern VOID SpicWaitWipDoneRtl8195A( SPIC_INIT_PARA + SpicInitPara ); // wait spi-flash status register[0] = 0 + +_LONG_CALL_ +extern VOID SpicEraseFlashRtl8195A( VOID ); // CE, flash chip erase + +_LONG_CALL_ +extern u32 SpicCmpDataForCalibrationRtl8195A( void ); // compare read_data and golden_data +#ifdef CONFIG_FPGA +_LONG_CALL_ +extern VOID SpicProgFlashForCalibrationRtl8195A( SPIC_INIT_PARA + SpicInitPara ); // program spi-flash +#endif +_LONG_CALL_ +extern VOID SpicLoadInitParaFromClockRtl8195A( u8 CpuClkMode, u8 BaudRate, + PSPIC_INIT_PARA pSpicInitPara ); + +_LONG_CALL_ +extern u8 SpicGetFlashStatusRtl8195A( SPIC_INIT_PARA SpicInitPara ); + +_LONG_CALL_ +extern VOID SpicTxCmdRtl8195A( u8 cmd, SPIC_INIT_PARA SpicInitPara ); + +struct ava_window +{ + u16 baud_rate; + u16 auto_length; + u32 dly_line_sp; + u32 dly_line_ep; }; -//----- ROM: SpicRxCmdRtl8195A -// recieve command -u8 SpicRxCmdRtl8195A(u8 cmd) + +#ifdef CONFIG_FPGA +HAL_ROM_DATA_SECTION +SPIC_INIT_PARA FPGASpicInitPara = {1, 1, 0, 0}; +#endif + +#if 0 +HAL_FLASH_DATA_ +SECTION SPIC_INIT_PARA SpicInitParaAllClk[CPU_CLK_TYPE_NO] = {{0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, +}; +#else +HAL_FLASH_DATA_SECTION +SPIC_INIT_PARA SpicInitParaAllClk[3][CPU_CLK_TYPE_NO]; +#endif + +extern SPIC_INIT_PARA SpicInitCPUCLK[4]; + +/* Send Flash Instruction with Data Phase */ +HAL_FLASH_TEXT_SECTION +VOID +SpicTxCmdWithDataRtl8195A +( + IN u8 cmd, + IN u8 DataPhaseLen, + IN u8 * pData, + IN SPIC_INIT_PARA SpicInitPara +) { - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, - (HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_ADDR_CH(3)|BIT_DATA_CH(3)|BIT_CTRL_TMOD(3)))) - | BIT_CTRL_TMOD(3)); // SpicOneBitMode +..., 40006000 = 40006000 & 0xFFF0FCFF | 0x300; - HAL_SPI_WRITE32(REG_SPIC_DR0, cmd); // 40006060 = cmd; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(1)); // 40006008 = 1; - while (HAL_SPI_READ32(REG_SPIC_SR) & BIT_BUSY); // 40006028 & 1 - return cmd; + u8 i; + DBG_SPIF_INFO( "%s(0x%x, 0x%x, 0x%x, 0x%x)\n", __func__, cmd, DataPhaseLen, pData, SpicInitPara ); + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + + if ( DataPhaseLen > 15 ) + { + DBG_SPIF_WARN( "SpicTxInstRtl8195A: Data Phase Leng too Big(%d)\n", DataPhaseLen ); + DataPhaseLen = 15; + } + + HAL_SPI_WRITE32( REG_SPIC_ADDR_LENGTH, DataPhaseLen ); + // set ctrlr0: TX mode + HAL_SPI_WRITE32( REG_SPIC_CTRLR0, + ( HAL_SPI_READ32( REG_SPIC_CTRLR0 ) & 0xFFF0FCFF ) ); + // set flash_cmd: wren to fifo + HAL_SPI_WRITE8( REG_SPIC_DR0, cmd ); + + //fill addr + for ( i = 0; i < DataPhaseLen; i++ ) + { + HAL_SPI_WRITE8( REG_SPIC_DR0, ( u8 ) * ( pData + i ) ); + } + + // Enable SPI_FLASH User Mode + HAL_SPI_WRITE32( REG_SPIC_SSIENR, BIT_SPIC_EN ); + // wait spic busy done + SpicWaitBusyDoneRtl8195A(); + + // Disable SPI_FLASH User Mode + // HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + + // wait flash busy done (wip=0) + //SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); + if( ( SpicInitParaAllClk[0][0].flashtype ) == FLASH_MICRON ) + SpicWaitOperationDoneRtl8195A( SpicInitPara ); + else + SpicWaitWipDoneRefinedRtl8195A( SpicInitPara ); } -//----- ROM: SpicWaitBusyDoneRtl8195A -// wait sr[0] = 0, wait transmission done -VOID SpicWaitBusyDoneRtl8195A(VOID) +HAL_FLASH_TEXT_SECTION +VOID +SpicTxFlashInstRtl8195A( + IN u8 cmd, + IN u8 DataPhaseLen, + IN u8 * pData +) { - while (HAL_SPI_READ32(REG_SPIC_SR) & BIT_BUSY); + SPIC_INIT_PARA SpicInitPara; + // Wait for flash busy done + SpicWaitWipDoneRefinedRtl8195A( SpicInitPara ); + DBG_8195A(); + + while( ( SpicGetFlashStatusRefinedRtl8195A( SpicInitPara ) & 0x02 ) == 0 ) + { + // Set flash_cmd: WREN to FIFO + //SpicTxCmdRtl8195A(0x06, SpicInitPara); + //Jason Deng modification 20141204 + SpicTxCmdWithDataRtl8195A( FLASH_CMD_WREN, 0, 0, SpicInitPara ); + } + + // Set flash_cmd to FIFO + SpicTxCmdWithDataRtl8195A( cmd, DataPhaseLen, pData, SpicInitPara ); + + if( ( SpicInitParaAllClk[0][0].flashtype ) == FLASH_MICRON ) + SpicWaitOperationDoneRtl8195A( SpicInitPara ); + else + { + // polling WEL + do + { + } + while( ( SpicGetFlashStatusRefinedRtl8195A( SpicInitPara ) & 0x02 ) != 0 ); + } } -//----- ROM: SpicGetFlashStatusRtl8195A -// RDSR, read spi-flash status register -u8 SpicGetFlashStatusRtl8195A(SPIC_INIT_PARA SpicInitPara) +HAL_FLASH_TEXT_SECTION +VOID +SpicDeepPowerDownFlashRtl8195A( + VOID +) { - HAL_SPI_WRITE32(REG_SPIC_CTRLR1, BIT_CTRL_NDF(1)); //40006004 = 1; + SPIC_INIT_PARA SpicInitPara; - u16 save_reg = HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH); // v2 = 4000611C; - HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, - (HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH) - & (~((BIT_MASK_RD_DUMMY_LENGTH) << BIT_SHIFT_RD_DUMMY_LENGTH))) - | SpicInitPara.RdDummyCyle); // 4000611C = v1 | (4000611C >> 16 << 16); - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, - (HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_ADDR_CH(3)|BIT_DATA_CH(3)|BIT_CTRL_TMOD(3)))) - | BIT_CTRL_TMOD(3)); // SpicOneBitMode +..., 40006000 = 40006000 & 0xFFF0FCFF | 0x300; - HAL_SPI_WRITE32(REG_SPIC_DR0, FLASH_CMD_RDSR); // 40006060 = 5; // RDSR (read status register) - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(1)); // 40006008 = 1; - while (HAL_SPI_READ32(REG_SPIC_SR) & BIT_BUSY); // 40006028 & 1 - u8 result = HAL_SPI_READ32(REG_SPIC_DR0); // v40006060; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, - (HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH) - & (~((BIT_MASK_RD_DUMMY_LENGTH) << BIT_SHIFT_RD_DUMMY_LENGTH))) - | save_reg); - return result; + if ( ( HAL_READ32( SYSTEM_CTRL_BASE, REG_SYS_EFUSE_SYSCFG6 ) & BIT( 25 ) ) && + ( ( ( ( u8 )HAL_READ32( SYSTEM_CTRL_BASE, REG_SYS_SYSTEM_CFG0 ) ) >> 4 ) >= 2 ) ) + { + SPI_FLASH_PIN_FCTRL( ON ); + // Wait for flash busy done + SpicWaitWipDoneRefinedRtl8195A( SpicInitPara ); + + while( ( SpicGetFlashStatusRefinedRtl8195A( SpicInitPara ) & 0x02 ) == 0 ) + { + // Set flash_cmd: WREN to FIFO + //SpicTxCmdRtl8195A(FLASH_CMD_WREN, SpicInitPara); + SpicTxCmdWithDataRtl8195A( FLASH_CMD_WREN, 0, 0, SpicInitPara ); + } + + DBG_8195A( "Deep power down\n" ); + // Set flash_cmd: Chip_erase to FIFO + //SpicTxCmdRtl8195A(FLASH_CMD_CE, SpicInitPara); + SpicTxCmdWithDataRtl8195A( FLASH_CMD_DP, 0, 0, SpicInitPara ); + + // polling WEL + do + { + } + while( ( SpicGetFlashStatusRefinedRtl8195A( SpicInitPara ) & 0x02 ) != 0 ); + } +} +//This funciton is only valid for Micron Flash +HAL_FLASH_TEXT_SECTION +VOID +SpicDieEraseFlashRtl8195A( + IN u32 Address +) +{ + u8 Addr[3]; + Addr[0] = ( Address >> 16 ) & 0xFF; + Addr[1] = ( Address >> 8 ) & 0xFF; + Addr[2] = Address & 0xFF; + SpicTxFlashInstRtl8195A( 0xC4, 3, Addr ); } -//----- ROM: SpicWaitWipDoneRtl8195A -// wait spi-flash status register[0] = 0 -VOID SpicWaitWipDoneRtl8195A(SPIC_INIT_PARA SpicInitPara) +HAL_FLASH_TEXT_SECTION +VOID +SpicBlockEraseFlashRtl8195A( + IN u32 Address +) { - while (SpicGetFlashStatusRtl8195A(SpicInitPara) & 1); + u8 Addr[3]; + DBG_8195A( "Erase Cmd Set\n" ); + // Set flash_cmd: Chip_erase to FIFO + Addr[0] = ( Address >> 16 ) & 0xFF; + Addr[1] = ( Address >> 8 ) & 0xFF; + Addr[2] = Address & 0xFF; + SpicTxFlashInstRtl8195A( FLASH_CMD_BE, 3, Addr ); } -//----- ROM: SpicTxCmdRtl8195A -// transfer command -VOID SpicTxCmdRtl8195A(u8 cmd, SPIC_INIT_PARA SpicInitPara) + +HAL_FLASH_TEXT_SECTION +VOID +SpicSectorEraseFlashRtl8195A( + IN u32 Address +) { - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, - HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_ADDR_CH(3)|BIT_DATA_CH(3)|BIT_CTRL_TMOD(3)))); // 40006000 &= 0xFFF0FCFF; - HAL_SPI_WRITE32(REG_SPIC_DR0, cmd); // 40006060 = cmd; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(1)); // 40006008 = 1; - while (HAL_SPI_READ32(REG_SPIC_SR) & BIT_BUSY); - while (SpicGetFlashStatusRtl8195A(SpicInitPara) & 1); + u8 Addr[3]; + Addr[0] = ( Address >> 16 ) & 0xFF; + Addr[1] = ( Address >> 8 ) & 0xFF; + Addr[2] = Address & 0xFF; + SpicTxFlashInstRtl8195A( FLASH_CMD_SE, 3, Addr ); } -//----- ROM: SpicSetFlashStatusRtl8195A -// WRSR, write spi-flash status register -VOID SpicSetFlashStatusRtl8195A(u32 data, SPIC_INIT_PARA SpicInitPara) + +HAL_FLASH_TEXT_SECTION +VOID +SpicWriteStatusFlashRtl8195A( + IN u32 Status +) { - u32 save_reg = HAL_SPI_READ32(REG_SPIC_ADDR_LENGTH); //v2 = 40006118; - SpicTxCmdRtl8195A(FLASH_CMD_WREN, SpicInitPara); // WREN (write enable) - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_CTRL_TMOD(3)))); // 40006000 &= 0xFFFFFCFF; - HAL_SPI_WRITE32(REG_SPIC_ADDR_LENGTH, BIT_CTRL_ADDR_PHASE_LENGTH(1)); // 40006118 = 1; - HAL_SPI_WRITE32(REG_SPIC_DR0, data); // 40006060 = v1; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(1)); //40006008 = 1; - while (HAL_SPI_READ32(REG_SPIC_SR) & BIT_BUSY); - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); //40006008 = 0; - HAL_SPI_WRITE32(REG_SPIC_ADDR_LENGTH, save_reg); - while (SpicGetFlashStatusRtl8195A(SpicInitPara) & 1); + u8 Buf[3]; + Buf[0] = Status & 0xFF; + Buf[1] = ( Status >> 8 ) & 0xFF; + //1 For MXIC, Status Register is 8-bit width; for Winbond, Status Reguster is 16-bit width + SpicTxFlashInstRtl8195A( FLASH_CMD_WRSR, 1, Buf ); } -int SpicCalibrationPattern[] = { 0x96969999, 0xFC66CC3F, 0x3CC33C0, 0x6231DCE5 }; // weak -//----- ROM: SpicCmpDataForCalibrationRtl8195A -// compare read_data and golden_data -u32 SpicCmpDataForCalibrationRtl8195A(VOID) +HAL_FLASH_TEXT_SECTION +VOID +SpicWriteProtectFlashRtl8195A( + IN u32 Protect +) { - int i; - for(i = 0; i < 4; i++) if (SpicCalibrationPattern[i] != HAL_READ32(SPI_FLASH_BASE, i<<2)) return 0; - return 1; + SPIC_INIT_PARA SpicInitPara; + u8 Status; + Status = SpicGetFlashStatusRefinedRtl8195A( SpicInitPara ); + + if ( Protect ) + { + Status |= 0x1c; // protect whole chip + } + else + { + Status &= ~0x1c; // Protect none + } + + SpicWriteStatusFlashRtl8195A( Status ); } -//----- ROM: SpicLoadInitParaFromClockRtl8195A -VOID SpicLoadInitParaFromClockRtl8195A (IN u8 CpuClkMode, IN u8 BaudRate, IN PSPIC_INIT_PARA pSpicInitPara) -//int __fastcall SpicLoadInitParaFromClockRtl8195A(int a1, int a2, int a3) + +HAL_FLASH_TEXT_SECTION +BOOLEAN +SpicFlashInitRtl8195A( + IN u8 SpicBitMode +) { - int spic_baud_rate = (HAL_SYS_CTRL_READ32(REG_SYS_EFUSE_SYSCFG6) >> BIT_SHIFT_SYS_SPIC_INIT_BAUD_RATE_SEL) & BIT_MASK_SYS_SPIC_INIT_BAUD_RATE_SEL; // (40000038 >> 26) & 3; - PSPIC_INIT_PARA_ROM spic_tab_rom = &SpicInitCPUCLK[spic_baud_rate]; - u8 DelayLine = spic_tab_rom->DelayLine; - u32 reg_data = HAL_SYS_CTRL_READ32(REG_SYS_SYSTEM_CFG1) & BIT_SYSCFG_ALDN_STS; // 400001F4 & 1; - if (reg_data) { - reg_data = HAL_SYS_CTRL_READ32(REG_SYS_EEPROM_CTRL0) & 0x20; // 400000E0 & 0x20; - if (reg_data) { - reg_data = HAL_SYS_CTRL_READ32(REG_SYS_EFUSE_SYSCFG6) & (1 << BIT_SHIFT_SYS_CPU_CLK_SEL); // 40000038 & 0x1000000; - if (reg_data) { - DelayLine = 3 * ((HAL_SYS_CTRL_READ32(REG_SYS_EFUSE_SYSCFG6) >> 16) & 0x1F) ; // 3 * ((v40000038 >> 16) & 0x1F); - reg_data = ((HAL_SYS_CTRL_READ32(REG_SYS_EFUSE_SYSCFG6) >> 16) & 0xFF) >> 5; + u32 DefRdDummyCycle = 0; + SPIC_INIT_PARA SpicInitPara; +#ifdef CONFIG_FPGA + SpicInitPara.BaudRate = FPGASpicInitPara.BaudRate; + SpicInitPara.RdDummyCyle = FPGASpicInitPara.RdDummyCyle; + SpicInitPara.DelayLine = FPGASpicInitPara.DelayLine; +#endif + + switch ( SpicBitMode ) + { + case SpicOneBitMode: + // DBG_8195A("Initial Spic One bit mode\n"); + // wait for flash busy done + SpicWaitWipDoneRefinedRtl8195A( SpicInitPara ); + // set auto mode + SpicConfigAutoModeRtl8195A( SpicBitMode ); + /* MXIC spec */ + DefRdDummyCycle = 0; + break; + + case SpicDualBitMode: + // DBG_8195A("Initial Spic Two bit mode\n"); +#ifdef CONFIG_FPGA + // program golden_data to golden_address and store golden_data in sram + SpicProgFlashForCalibrationRtl8195A( SpicInitPara ); +#endif + // set auto mode + SpicConfigAutoModeRtl8195A( SpicBitMode ); + /* MXIC spec */ +#if FLASH_RD_2IO_EN + DefRdDummyCycle = FLASH_DM_CYCLE_2IO; +#endif +#if FLASH_RD_2O_EN + DefRdDummyCycle = FLASH_DM_CYCLE_2O; +#endif + break; + + case SpicQuadBitMode: + DBG_8195A( "Initial Spic Four bit mode\n" ); +#ifdef CONFIG_FPGA + // program golden_data to golden_address and store golden_data in sram + SpicProgFlashForCalibrationRtl8195A( SpicInitPara ); +#endif + // set auto mode + SpicConfigAutoModeRtl8195A( SpicBitMode ); + // set 4bit-mode + SpicSetFlashStatusRefinedRtl8195A( 0x40, SpicInitPara ); + /* MXIC spec */ +#if FLASH_RD_4IO_EN + DefRdDummyCycle = FLASH_DM_CYCLE_4IO; +#endif +#if FLASH_RD_4O_EN + DefRdDummyCycle = FLASH_DM_CYCLE_4O; +#endif + break; + + default: + DBG_8195A( "No Support SPI Mode!!!!!!!!\n" ); + break; + } + + SpicReadIDRtl8195A(); + + if ( !SpicCalibrationRtl8195A( SpicBitMode, DefRdDummyCycle ) ) + { + DBG_8195A( "SPI calibration fail and recover one bit mode\n" ); + SpicLoadInitParaFromClockRtl8195A( 0, 0, &SpicInitPara ); + SpicInitRefinedRtl8195A( SpicInitPara.BaudRate, SpicOneBitMode ); + SpicConfigAutoModeRtl8195A( SpicOneBitMode ); + return _FALSE; + } + + return _TRUE; +} + +HAL_FLASH_TEXT_SECTION +VOID +SpicUserProgramRtl8195A +( + //IN flash_t *obj, + IN u8 * data, + IN SPIC_INIT_PARA SpicInitPara, + IN u32 addr, + IN u32 * LengthInfo +) +{ + u32 Info; + u32 Length = ( u32 ) * LengthInfo; + u32 OccuSize; + u32 writeword; + u32 lastwriteword; + u32 ProgramLength; + u32 instruction; + u32 PageSize; + u8 addrbyte[3]; + u8 UnalignOffset; + u8 lastunalignoffset; + u8 index; + u8 * ptr; + u8 * buff; + UnalignOffset = 0; + lastunalignoffset = 0; + writeword = 0; + lastwriteword = 0; + ProgramLength = 0; + buff = data; + PageSize = 256; + OccuSize = addr & 0xFF; + + if( OccuSize ) + { + if( ( Length >= PageSize ) || ( ( OccuSize + Length ) >= PageSize ) ) + ProgramLength = PageSize - OccuSize; + else + ProgramLength = Length; + } + else //program from the beginning of the page + { + if( Length >= PageSize ) + ProgramLength = PageSize; + else + ProgramLength = Length; + } + + *LengthInfo -= ProgramLength; + + if( addr & 0x03 ) + { + UnalignOffset = ( addr & 0x03 ); + addr -= UnalignOffset; + writeword = HAL_READ32( SPI_FLASH_BASE, addr ); + ptr = ( u8 * ) &writeword + UnalignOffset; + UnalignOffset = 4 - UnalignOffset; + + for( index = 0; index < UnalignOffset ; index++ ) + { + *ptr = *buff; + buff++; + ptr++; + ProgramLength--; + + if( ProgramLength == 0 ) + break; + } + } + else + { + if( ProgramLength >= 4 ) + { + writeword = ( u32 )( *buff ) | ( u32 )( ( *( buff + 1 ) ) << 8 ) | ( u32 )( ( * + ( buff + 2 ) ) << 16 ) | ( u32 )( ( *( buff + 3 ) ) << 24 ); + } + } + + //address already align + if( ProgramLength & 0x3 ) + { + lastunalignoffset = ProgramLength & 0x3; + + if( UnalignOffset ) + lastwriteword = HAL_READ32( SPI_FLASH_BASE, ( addr + 4 ) + ProgramLength - lastunalignoffset ); + else + lastwriteword = HAL_READ32( SPI_FLASH_BASE, addr + ProgramLength - lastunalignoffset ); + + buff += ( ProgramLength - lastunalignoffset ); + ptr = ( u8 * ) &lastwriteword; + + for( index = 0; index < lastunalignoffset; index++ ) + { + *ptr = *buff; + buff++; + ptr++; + } + + if( UnalignOffset == 0 ) + if( ProgramLength < 4 ) + { + writeword = lastwriteword; + ProgramLength = 0; } + } + + addrbyte[2] = ( addr & 0xFF0000 ) >> 16; + addrbyte[1] = ( addr & 0xFF00 ) >> 8; + addrbyte[0] = addr & 0xFF; + instruction = FLASH_CMD_PP | ( addrbyte[2] << 8 ) | ( addrbyte[1] << 16 ) | ( addrbyte[0] << 24 ); + Info = HAL_SPI_READ32( REG_SPIC_ADDR_LENGTH ); + //Store current setting of Address length + // Set flash_cmd: WREN to FIFO + SpicTxCmdRtl8195A( FLASH_CMD_WREN, SpicInitPara ); + // Disable SPI_FLASH + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + // set ctrlr0: TX mode + HAL_SPI_WRITE32( REG_SPIC_CTRLR0, + ( HAL_SPI_READ32( REG_SPIC_CTRLR0 ) & ( ~ BIT_TMOD( 3 ) ) ) ); + HAL_SPI_WRITE32( REG_SPIC_ADDR_LENGTH, BIT_ADDR_PHASE_LENGTH( 1 ) ); + HAL_SPI_WRITE32( REG_SPIC_DR0, instruction ); + HAL_SPI_WRITE32( REG_SPIC_DR0, writeword ); + + if( UnalignOffset == 0 ) + { + if( ProgramLength >= 4 ) + { + buff = data + 4; + ProgramLength -= 4; } } - pSpicInitPara->BaudRate = spic_tab_rom->BaudRate; - pSpicInitPara->RdDummyCyle = reg_data + spic_tab_rom->RdDummyCyle; - pSpicInitPara->DelayLine = DelayLine; -} + else + buff = data + UnalignOffset; -//----- ROM: SpicInitRtl8195A -// spi-flash controller initialization -VOID SpicInitRtl8195A(u8 InitBaudRate, u8 SpicBitMode) -{ - SPIC_INIT_PARA SpicInitPara; //char v5; - u32 CpuClkMode = (HAL_PERI_ON_READ32(REG_SYS_CLK_CTRL1) - >> BIT_SHIFT_PESOC_OCP_CPU_CK_SEL) & BIT_MASK_PESOC_OCP_CPU_CK_SEL; // v3 = (40000014 >> 4) & 7; - SpicLoadInitParaFromClockRtl8195A(CpuClkMode, InitBaudRate, &SpicInitPara); - HAL_SPI_READ32(REG_SPIC_CTRLR1); // 0x40006004; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); //40006008 = 0; - HAL_SPI_WRITE32(REG_SPIC_BAUDR, InitBaudRate); // 40006014 = v2; - HAL_SPI_WRITE32(REG_SPIC_SER, BIT_CTRL_SER(1)); // 40006010 = 1; - HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, - (HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH) - & (~((BIT_MASK_RD_DUMMY_LENGTH) << BIT_SHIFT_RD_DUMMY_LENGTH))) - | SpicInitPara.RdDummyCyle); // 4000611C = v1 | (4000611C >> 16 << 16); - HAL_PERI_ON_WRITE32(REG_PESOC_MEM_CTRL, - (HAL_PERI_ON_READ32(REG_PESOC_MEM_CTRL) & BIT_MASK_PESOC_FLASH_DDL_CTRL << BIT_SHIFT_PESOC_FLASH_DDL_CTRL) - | SpicInitPara.DelayLine); // 40000300 = 40000300 & 0xFFFFFF00 | v7; - HAL_SPI_WRITE32(REG_SPIC_CTRLR1, BIT_CTRL_NDF(4)); //40006004 = 4; - if (SpicBitMode == SpicDualBitMode) - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, - (HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_CTRL_CMD_CH(3)|BIT_ADDR_CH(3)|BIT_DATA_CH(3)))) - | BIT_ADDR_CH(1) | BIT_DATA_CH(1)); // 40006000 = 40006000 & 0xFFC0FFFF | 0x50000; - else if (SpicBitMode >= SpicDualBitMode) { - if (SpicBitMode == SpicQuadBitMode) - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, - (HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_CTRL_CMD_CH(3)|BIT_ADDR_CH(3)|BIT_DATA_CH(3)))) - | BIT_ADDR_CH(2) | BIT_DATA_CH(2)); // 40006000 = 40006000 & 0xFFC0FFFF | 0xA0000; + //Pre-load data before enabling + index = 0; + + while( ProgramLength > 4 ) + { + if( ( u32 )buff & 0x03 ) + { + //while(ProgramLength >= 4){ + writeword = ( u32 )( *buff ) | ( ( u32 )( *( buff + 1 ) ) << 8 ) | ( ( u32 )( * + ( buff + 2 ) ) << 16 ) | ( ( u32 )( *( buff + 3 ) ) << 24 ); + HAL_SPI_WRITE32( REG_SPIC_DR0, writeword ); + ProgramLength -= 4; + buff += 4; + //} + } + else + { + //while(ProgramLength >= 4){ + HAL_SPI_WRITE32( REG_SPIC_DR0, ( u32 ) * ( ( u32 * )buff ) ); + ProgramLength -= 4; + buff += 4; + //} + } + + index++; + + if( index >= 6 ) + break; } - else // (SpicBitMode == SpicOneBitMode) - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, - HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_CTRL_CMD_CH(3)|BIT_ADDR_CH(3)|BIT_DATA_CH(3)))); //40006000 &= 0xFFC0FFFF; + + // Enable SPI_FLASH User Mode + HAL_SPI_WRITE32( REG_SPIC_SSIENR, BIT_SPIC_EN ); + + if( ( u32 )buff & 0x03 ) + { + while( ProgramLength >= 4 ) + { + writeword = ( u32 )( *buff ) | ( ( u32 )( *( buff + 1 ) ) << 8 ) | ( ( u32 )( * + ( buff + 2 ) ) << 16 ) | ( ( u32 )( *( buff + 3 ) ) << 24 ); + HAL_SPI_WRITE32( REG_SPIC_DR0, writeword ); + ProgramLength -= 4; + buff += 4; + } + } + else + { + while( ProgramLength >= 4 ) + { + HAL_SPI_WRITE32( REG_SPIC_DR0, ( u32 ) * ( ( u32 * )buff ) ); + ProgramLength -= 4; + buff += 4; + } + } + + if( ProgramLength > 0 ) + { + HAL_SPI_WRITE32( REG_SPIC_DR0, lastwriteword ); + } + + // wait spic busy done + SpicWaitBusyDoneRtl8195A(); + + // wait flash busy done (wip=0) + if( SpicInitPara.flashtype == FLASH_MICRON ) + { + SpicWaitOperationDoneRtl8195A( SpicInitPara ); + } + else + { + SpicWaitWipDoneRtl8195A( SpicInitPara ); + } + + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + //REG_SPIC_ADDR_LENGTH cannot be programmed if SSIENR is active + //Here to restore the setting of address length + HAL_SPI_WRITE32( REG_SPIC_ADDR_LENGTH, Info ); } -//----- ROM: SpicEraseFlashRtl8195A -// CE, flash chip erase -VOID SpicEraseFlashRtl8195A(VOID) +HAL_FLASH_TEXT_SECTION +VOID +SpicReadIDRtl8195A( + VOID +) +{ + u32 RdData; + u32 RetryNum; + SPIC_INIT_PARA SpicInitPara;// = *PSpicInitPara; + u8 i, j; + DBG_SPIF_INFO( "%s(0x%x)\n", __func__, SpicInitPara ); + /* Disable SPI_FLASH User Mode */ + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + /* Set Ctrlr1; 1 byte data frames */ + HAL_SPI_WRITE32( REG_SPIC_CTRLR1, BIT_NDF( 3 ) ); + /* Send flash RX command and read the data */ + SpicRxCmdRefinedRtl8195A( FLASH_CMD_RDID, SpicInitPara ); + RdData = HAL_SPI_READ32( REG_SPIC_DR0 ); + SpicInitPara.id[0] = RdData & 0xFF; + SpicInitPara.id[1] = ( RdData >> 8 ) & 0xFF; + SpicInitPara.id[2] = ( RdData >> 16 ) & 0xFF; + + for( RetryNum = 0; RetryNum < 3; RetryNum++ ) + { + if( ( SpicInitPara.id[0] != 0 ) && ( SpicInitPara.id[0] != 0xFF ) ) + { + if( SpicInitPara.id[0] == 0x20 ) + SpicInitPara.flashtype = FLASH_MICRON; + else if( SpicInitPara.id[0] == 0xC2 ) + SpicInitPara.flashtype = FLASH_MXIC; + else if( SpicInitPara.id[0] == 0xEF ) + SpicInitPara.flashtype = FLASH_WINBOND; + else + SpicInitPara.flashtype = FLASH_OTHERS; + + break; + } + else + { + if( RetryNum == 2 ) + DBG_8195A( "Invalid ID\n" ); + } + } + + for( i = 0; i < 3; i++ ) + { + for ( j = 0; j < CPU_CLK_TYPE_NO; j++ ) + { + SpicInitParaAllClk[i][j].id[0] = SpicInitPara.id[0]; + SpicInitParaAllClk[i][j].id[1] = SpicInitPara.id[1]; + SpicInitParaAllClk[i][j].id[2] = SpicInitPara.id[2]; + SpicInitParaAllClk[i][j].flashtype = SpicInitPara.flashtype; + } + } + + /* Disable SPI_FLASH User Mode */ + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); +} + +HAL_FLASH_TEXT_SECTION +u32 +SpicCalibrationRtl8195A +( + IN u8 SpicBitMode, + IN u32 DefRdDummyCycle +) +{ + u32 rd_data, /*id_no,*/ baudr, autolen, dly_line; + u32 total_ava_wds = 0; + u32 tmp_str_pt, tmp_end_pt, pass, last_pass; + struct ava_window max_wd; + u32 CpuType; + SPIC_INIT_PARA SpicInitPara; + CpuType = ( ( HAL_READ32( SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1 ) & ( 0x70 ) ) >> 4 ); +#if SPIC_CALIBRATION_IN_NVM + + if ( !SpicInitParaAllClk[SpicBitMode][CpuType].Valid ) + { + SpicNVMCalLoad( SpicBitMode, CpuType ); + } + +#endif + + if ( SpicInitParaAllClk[SpicBitMode][CpuType].Valid ) + { + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + HAL_SPI_WRITE32( REG_SPIC_BAUDR, + ( SpicInitParaAllClk[SpicBitMode][CpuType].BaudRate & 0x00000FFF ) ); + rd_data = HAL_SPI_READ32( REG_SPIC_AUTO_LENGTH ); + rd_data = ( rd_data & 0xFFFF0000 ) | ( SpicInitParaAllClk[SpicBitMode][CpuType].RdDummyCyle & + 0x0000FFFF ); + HAL_SPI_WRITE32( REG_SPIC_AUTO_LENGTH, rd_data ); + rd_data = SpicInitParaAllClk[SpicBitMode][CpuType].DelayLine; + WR_DATA( SPI_DLY_CTRL_ADDR, ( ( RD_DATA( SPI_DLY_CTRL_ADDR ) & 0xFFFFFF00 ) | + ( rd_data & 0x000000FF ) ) ); + // Enable SPI_FLASH User Mode + HAL_SPI_WRITE32( REG_SPIC_SSIENR, BIT_SPIC_EN ); + SpicWaitWipDoneRefinedRtl8195A( SpicInitPara ); + pass = SpicCmpDataForCalibrationRtl8195A(); + + if ( pass ) + { + // Check the Magic Pattern OK + return 1; + } + } + + // calibration + DBG_8195A( "SPI calibration\n" ); + max_wd.auto_length = 0; + max_wd.baud_rate = 0; + max_wd.dly_line_ep = 0; + max_wd.dly_line_sp = 0; + + for( baudr = MIN_BAUDRATE; baudr < ( MAX_BAUDRATE + 1 ); baudr++ ) + { + // Disable SPI_FLASH User Mode + if( baudr == MIN_BAUDRATE ) + if( SpicBitMode == SpicOneBitMode ) + continue; + + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + HAL_SPI_WRITE32( REG_SPIC_BAUDR, BIT_SCKDV( baudr ) ); + // Enable SPI_FLASH User Mode + HAL_SPI_WRITE32( REG_SPIC_SSIENR, BIT_SPIC_EN ); + //DBG_8195A("(0x14)Baudr: 0x%x\n",HAL_SPI_READ32(REG_SPIC_BAUDR)); + + for( autolen = ( DefRdDummyCycle * 2 * baudr ); + autolen < ( DefRdDummyCycle * 2 * baudr + MAX_AUTOLEN ); autolen++ ) + { + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + rd_data = HAL_SPI_READ32( REG_SPIC_AUTO_LENGTH ); + rd_data = ( rd_data & 0xFFFF0000 ) | ( 0x0000FFFF & autolen ); + HAL_SPI_WRITE32( REG_SPIC_AUTO_LENGTH, rd_data ); + // Enable SPI_FLASH User Mode + HAL_SPI_WRITE32( REG_SPIC_SSIENR, BIT_SPIC_EN ); + //DBG_8195A("Auto length: 0x%x\n",autolen); + //DBG_8195A("(0x11C) Auto address length register: 0x%x\n",HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH)); + tmp_str_pt = MAX_DLYLINE; + tmp_end_pt = 0; + last_pass = 0; + + for( dly_line = 0; dly_line <= MAX_DLYLINE; dly_line++ ) + { + rd_data = RD_DATA( SPI_DLY_CTRL_ADDR ); + rd_data = ( rd_data & 0xFFFFFF00 ) | ( dly_line & 0x000000FF ); + WR_DATA( SPI_DLY_CTRL_ADDR, rd_data ); + //DBG_8195A("SPI_DLY_CTRL_ADDR: 0x%x\n",RD_DATA(SPI_DLY_CTRL_ADDR)); + pass = SpicCmpDataForCalibrationRtl8195A(); + + if( pass ) // PASS + { + if( last_pass == 0 ) + { + tmp_str_pt = dly_line; + total_ava_wds++; + } + + if( dly_line == MAX_DLYLINE ) + { + tmp_end_pt = dly_line; + + if( total_ava_wds == 1 ) + { + max_wd.baud_rate = baudr; + max_wd.auto_length = autolen; + max_wd.dly_line_sp = tmp_str_pt; + max_wd.dly_line_ep = tmp_end_pt; + } + else + { + if( ( tmp_end_pt - tmp_str_pt ) > ( max_wd.dly_line_ep - max_wd.dly_line_sp ) ) + { + max_wd.baud_rate = baudr; + max_wd.auto_length = autolen; + max_wd.dly_line_sp = tmp_str_pt; + max_wd.dly_line_ep = tmp_end_pt; + } + } + } + + last_pass = 1; + } + else // FAIL + { + if( last_pass == 1 ) + { + tmp_end_pt = dly_line; + + if( total_ava_wds == 1 ) + { + max_wd.baud_rate = baudr; + max_wd.auto_length = autolen; + max_wd.dly_line_sp = tmp_str_pt; + max_wd.dly_line_ep = tmp_end_pt; + } + else + { + if( ( tmp_end_pt - tmp_str_pt ) > ( max_wd.dly_line_ep - max_wd.dly_line_sp ) ) + { + max_wd.baud_rate = baudr; + max_wd.auto_length = autolen; + max_wd.dly_line_sp = tmp_str_pt; + max_wd.dly_line_ep = tmp_end_pt; + } + } + } + + last_pass = 0; + } + } + + //DBG_8195A("total wds: %d\n",total_ava_wds); + //DBG_8195A("Baud:%x; auto_length:%x; Delay start:%x; Delay end:%x\n",max_wd.baud_rate, max_wd.auto_length,max_wd.dly_line_sp, max_wd.dly_line_ep); + } + + if ( total_ava_wds ) + { + DBG_8195A( "Find the avaiable window\n" ); + break; + } + } + + if( total_ava_wds == 0 ) + { + return 0; + } + else + { + // set baudr, auto_length, and delay_line + DBG_8195A( "Baud:%x; auto_length:%x; Delay start:%x; Delay end:%x\n", max_wd.baud_rate, + max_wd.auto_length, max_wd.dly_line_sp, max_wd.dly_line_ep ); + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + HAL_SPI_WRITE32( REG_SPIC_BAUDR, ( max_wd.baud_rate & 0x00000FFF ) ); + SpicInitParaAllClk[SpicBitMode][CpuType].BaudRate = max_wd.baud_rate; + rd_data = HAL_SPI_READ32( REG_SPIC_AUTO_LENGTH ); + rd_data = ( rd_data & 0xFFFF0000 ) | ( max_wd.auto_length & 0x0000FFFF ); + HAL_SPI_WRITE32( REG_SPIC_AUTO_LENGTH, rd_data ); + SpicInitParaAllClk[SpicBitMode][CpuType].RdDummyCyle = max_wd.auto_length; + rd_data = ( ( max_wd.dly_line_sp + max_wd.dly_line_ep ) >> 1 ); + WR_DATA( SPI_DLY_CTRL_ADDR, ( ( RD_DATA( SPI_DLY_CTRL_ADDR ) & 0xFFFFFF00 ) | + ( rd_data & 0x000000FF ) ) ); + SpicInitParaAllClk[SpicBitMode][CpuType].DelayLine = rd_data; + SpicInitParaAllClk[SpicBitMode][CpuType].Valid = 1; + // Enable SPI_FLASH User Mode + HAL_SPI_WRITE32( REG_SPIC_SSIENR, BIT_SPIC_EN ); + SpicWaitWipDoneRefinedRtl8195A( SpicInitPara ); +#if SPIC_CALIBRATION_IN_NVM + SpicNVMCalStore( SpicBitMode, CpuType ); +#endif + return 1; + } +} + + +HAL_FLASH_TEXT_SECTION +VOID +SpicConfigAutoModeRtl8195A +( + IN u8 SpicBitMode +) +{ + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + + if ( SpicOneBitMode == SpicBitMode ) + { + // set write cmd (ppiix4: 0x38) + HAL_SPI_WRITE32( REG_SPIC_WRITE_QUAD_ADDR_DATA, 0x38 ); + // set read cmd (readiox4: 0xEB) + HAL_SPI_WRITE32( REG_SPIC_READ_QUAD_ADDR_DATA, 0xEB ); + HAL_SPI_WRITE32( REG_SPIC_VALID_CMD, + ( HAL_SPI_READ32( REG_SPIC_VALID_CMD ) & ( ~( + BIT_WR_QUAD_II | + BIT_WR_QUAD_I | + BIT_WR_DUAL_II | + BIT_WR_DUAL_I | + BIT_RD_QUAD_IO | + BIT_RD_QUAD_O | + BIT_RD_DUAL_IO | + BIT_RD_DUAL_I ) ) ) ); //Disable all the four and two bit commands. + } + + if ( SpicDualBitMode == SpicBitMode ) + { +#if FLASH_RD_2IO_EN + HAL_SPI_WRITE32( REG_SPIC_READ_DUAL_ADDR_DATA, FLASH_CMD_2READ ); +#endif +#if FLASH_RD_2O_EN + HAL_SPI_WRITE32( REG_SPIC_READ_DUAL_DATA, FLASH_CMD_DREAD ); +#endif + HAL_SPI_WRITE32( REG_SPIC_VALID_CMD, + ( HAL_SPI_READ32( REG_SPIC_VALID_CMD ) | ( FLASH_VLD_DUAL_CMDS ) ) ); + } + + if ( SpicQuadBitMode == SpicBitMode ) + { +#if FLASH_WR_4IO_EN + HAL_SPI_WRITE32( REG_SPIC_WRITE_QUAD_ADDR_DATA, FLASH_CMD_4PP ); +#endif +#if FLASH_RD_4IO_EN + HAL_SPI_WRITE32( REG_SPIC_READ_QUAD_ADDR_DATA, FLASH_CMD_4READ ); +#endif +#if FLASH_RD_4O_EN + HAL_SPI_WRITE32( REG_SPIC_READ_QUAD_DATA, FLASH_CMD_QREAD ); +#endif + HAL_SPI_WRITE32( REG_SPIC_VALID_CMD, + ( HAL_SPI_READ32( REG_SPIC_VALID_CMD ) | FLASH_VLD_QUAD_CMDS ) ); + } +} + + +/** + * @brief SpicWaitWipDoneRefinedRtl8195A. Wait for flash ready. + * + * @param IN SPIC_INIT_PARA SpicInitPara: spic init parameters with timing setting + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION +VOID +SpicWaitWipDoneRefinedRtl8195A( + IN SPIC_INIT_PARA SpicInitPara +) +{ + DBG_SPIF_INFO( "%s(0x%x)\n", __func__, SpicInitPara ); + + do + { + } + while( ( SpicGetFlashStatusRefinedRtl8195A( SpicInitPara ) & 0x01 ) ); +} + + +#if 1 +HAL_FLASH_TEXT_SECTION +u8 +SpicGetFlashFlagRtl8195A +( + IN SPIC_INIT_PARA SpicInitPara +) +{ + u32 RdData; + DBG_SPIF_INFO( "%s(0x%x)\n", __func__, SpicInitPara ); + /* Disable SPI_FLASH User Mode */ + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + /* Set Ctrlr1; 1 byte data frames */ + HAL_SPI_WRITE32( REG_SPIC_CTRLR1, BIT_NDF( 1 ) ); + /* Send flash RX command and read the data */ + SpicRxCmdRefinedRtl8195A( 0x70, SpicInitPara ); + RdData = HAL_SPI_READ8( REG_SPIC_DR0 ); + /* Disable SPI_FLASH User Mode */ + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + + if( RdData & 0x2 ) + { + DBG_SPIF_WARN( "Attempts to Program / Erase Protected Area.\n" ); + SpicTxCmdWithDataRtl8195A( 0x50, 0, 0, + SpicInitPara ); //Clear Error Bit & Write Enable of Flag Status Register + } + + return RdData; +} + +HAL_FLASH_TEXT_SECTION +VOID +SpicWaitOperationDoneRtl8195A +( + IN SPIC_INIT_PARA SpicInitPara +) +{ + DBG_SPIF_INFO( "%s(0x%x)\n", __func__, SpicInitPara ); + + do + { + } + while( !( SpicGetFlashFlagRtl8195A( SpicInitPara ) & 0x80 ) ); +} + +#endif +/** + * @brief SpicRxCmdRefinedRtl8195A. To send flash RX command. + * Timing store/restore is implemented inside. + * + * @param IN u8 cmd: flash RX command + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION +VOID +SpicRxCmdRefinedRtl8195A( + IN u8 cmd, + IN SPIC_INIT_PARA SpicInitPara +) +{ + u32 RdDummyCycle; + u32 BaudRate; + u32 BaudRate12bit; + u32 DelayLine; + u32 DelayLine8bit; + u32 AutoLength = 0; + u8 CpuClk = ( ( HAL_READ32( SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1 ) & ( 0x70 ) ) >> 4 ); + PSPIC_INIT_PARA PSpicInitParaLocal = NULL; + SPIC_INIT_PARA TmpSpicInitPara; +#ifdef CONFIG_FPGA + PSpicInitParaLocal = &TmpSpicInitPara; + PSpicInitParaLocal->BaudRate = FPGASpicInitPara.BaudRate; + PSpicInitParaLocal->RdDummyCyle = FPGASpicInitPara.RdDummyCyle; + PSpicInitParaLocal->DelayLine = FPGASpicInitPara.DelayLine; +#else + + if ( SpicInitParaAllClk[SpicOneBitMode][CpuClk].Valid ) + { + PSpicInitParaLocal = &( SpicInitParaAllClk[SpicOneBitMode][CpuClk] ); + } + else + { + PSpicInitParaLocal = &TmpSpicInitPara; + SpicLoadInitParaFromClockRtl8195A( CpuClk, 1, PSpicInitParaLocal ); + } + +#endif +#if 0 + DBG_8195A( "!cpuclk:%x\n", CpuClk ); + DBG_8195A( "!baud:%x\n", PSpicInitParaLocal->BaudRate ); + DBG_8195A( "!delay:%x\n", PSpicInitParaLocal->DelayLine ); + DBG_8195A( "!dummy:%x\n", PSpicInitParaLocal->RdDummyCyle ); +#endif + DBG_SPIF_INFO( "%s(0x%x, 0x%x)\n", __func__, cmd, PSpicInitParaLocal ); + /* Store rd_dummy_cycle */ + AutoLength = HAL_SPI_READ32( REG_SPIC_AUTO_LENGTH ); + RdDummyCycle = AutoLength & BIT_MASK_RD_DUMMY_LENGTH; + HAL_SPI_WRITE32( REG_SPIC_AUTO_LENGTH, + ( ( AutoLength & ( ~BIT_MASK_RD_DUMMY_LENGTH ) ) | ( PSpicInitParaLocal->RdDummyCyle ) ) ); + /* Store baud rate */ + BaudRate = HAL_SPI_READ32( REG_SPIC_BAUDR ); + BaudRate12bit = ( BaudRate & BIT_MASK_SCKDV ); + HAL_SPI_WRITE32( REG_SPIC_BAUDR, + ( ( BaudRate & ( ~BIT_MASK_SCKDV ) ) | ( PSpicInitParaLocal->BaudRate ) ) ); + /* Store delay line */ + DelayLine = HAL_READ32( SYSTEM_CTRL_BASE, REG_PESOC_MEM_CTRL ); + DelayLine8bit = ( DelayLine & BIT_MASK_PESOC_FLASH_DDL_CTRL ); + HAL_WRITE32( SYSTEM_CTRL_BASE, REG_PESOC_MEM_CTRL, + ( ( DelayLine & ( ~BIT_MASK_PESOC_FLASH_DDL_CTRL ) ) | ( PSpicInitParaLocal->DelayLine ) ) ); + //HAL_WRITE32(SYSTEM_CTRL_BASE, REG_PESOC_MEM_CTRL, ((DelayLine & (~BIT_MASK_PESOC_FLASH_DDL_CTRL))|DelayLine8bit)); + /* Disable SPI_FLASH User Mode */ + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + /* set ctrlr0: RX_mode */ + HAL_SPI_WRITE32( REG_SPIC_CTRLR0, + ( ( HAL_SPI_READ32( REG_SPIC_CTRLR0 ) & 0xFFF0FFFF ) | BIT_TMOD( 3 ) ) ); + /* set flash_cmd: write cmd to fifo */ + HAL_SPI_WRITE8( REG_SPIC_DR0, cmd ); + /* Enable SPI_FLASH User Mode */ + HAL_SPI_WRITE32( REG_SPIC_SSIENR, BIT_SPIC_EN ); + /* Wait spic busy done */ + SpicWaitBusyDoneRtl8195A(); + /* Disable SPI_FLASH User Mode */ + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + /* Recover rd_dummy_cycle */ + AutoLength = HAL_SPI_READ32( REG_SPIC_AUTO_LENGTH ); + AutoLength = AutoLength & 0xFFFF0000; + HAL_SPI_WRITE32( REG_SPIC_AUTO_LENGTH, ( AutoLength | RdDummyCycle ) ); + /* Recover baud rate */ + BaudRate = HAL_SPI_READ32( REG_SPIC_BAUDR ); + BaudRate = ( BaudRate & ( ~BIT_MASK_SCKDV ) ); + HAL_SPI_WRITE32( REG_SPIC_BAUDR, ( BaudRate | BaudRate12bit ) ); + /* Recover delay line */ + DelayLine = HAL_READ32( SYSTEM_CTRL_BASE, REG_PESOC_MEM_CTRL ); + DelayLine = ( DelayLine & ( ~BIT_MASK_PESOC_FLASH_DDL_CTRL ) ); + HAL_WRITE32( SYSTEM_CTRL_BASE, REG_PESOC_MEM_CTRL, ( DelayLine | DelayLine8bit ) ); +} + +/** + * @brief SpicGetFlashStatusRefinedRtl8195A. For the exchange between one- and two- + * bit mode, the spic timing setting (baud, rd_dummy_cycle (ATUO_LENGTH) + * and delay line) should be changed according to the mode used. + * + * @param IN SPIC_INIT_PARA SpicInitPara: spic init parameters with timing setting + * + * @retval u8 flash status register value + */ +HAL_FLASH_TEXT_SECTION +u8 +SpicGetFlashStatusRefinedRtl8195A( + IN SPIC_INIT_PARA SpicInitPara +) +{ + u32 RdData; + DBG_SPIF_INFO( "%s(0x%x)\n", __func__, SpicInitPara ); + /* Disable SPI_FLASH User Mode */ + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + /* Set Ctrlr1; 1 byte data frames */ + HAL_SPI_WRITE32( REG_SPIC_CTRLR1, BIT_NDF( 1 ) ); + /* Send flash RX command and read the data */ + SpicRxCmdRefinedRtl8195A( FLASH_CMD_RDSR, SpicInitPara ); + RdData = HAL_SPI_READ8( REG_SPIC_DR0 ); + /* Disable SPI_FLASH User Mode */ + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + return RdData; +} + +/** + * @brief SpicInitRefinedRtl8195A. + * + * @param IN u8 InitBaudRate, + * IN u8 SpicBitMode + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION +VOID +SpicInitRefinedRtl8195A( + IN u8 InitBaudRate, + IN u8 SpicBitMode +) +{ + u32 Value32; + SPIC_INIT_PARA SpicInitPara; + PSPIC_INIT_PARA PSpicInitParaLocal; + PSpicInitParaLocal = &SpicInitPara; +#ifdef CONFIG_FPGA + PSpicInitParaLocal->BaudRate = FPGASpicInitPara.BaudRate; + PSpicInitParaLocal->RdDummyCyle = FPGASpicInitPara.RdDummyCyle; + PSpicInitParaLocal->DelayLine = FPGASpicInitPara.DelayLine; +#else + u8 CpuClk; + CpuClk = ( ( ( u8 )( HAL_READ32( SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1 ) & ( 0x70 ) ) ) >> 4 ); + + if ( SpicInitParaAllClk[SpicBitMode][CpuClk].Valid ) + { + PSpicInitParaLocal = &( SpicInitParaAllClk[SpicBitMode][CpuClk] ); + } + else + { + SpicLoadInitParaFromClockRtl8195A( CpuClk, 1, PSpicInitParaLocal ); + } + +#endif + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + HAL_SPI_WRITE32( REG_SPIC_BAUDR, BIT_SCKDV( InitBaudRate ) ); + HAL_SPI_WRITE32( REG_SPIC_SER, BIT_SER ); + Value32 = HAL_SPI_READ32( REG_SPIC_AUTO_LENGTH ); + HAL_SPI_WRITE32( REG_SPIC_AUTO_LENGTH, + ( ( Value32 & 0xFFFF0000 ) | BIT_RD_DUMMY_LENGTH( PSpicInitParaLocal->RdDummyCyle ) ) ); + HAL_WRITE32( PERI_ON_BASE, REG_PESOC_MEM_CTRL, + ( ( HAL_READ32( PERI_ON_BASE, REG_PESOC_MEM_CTRL ) & 0xFFFFFF00 ) | + PSpicInitParaLocal->DelayLine ) ); + HAL_SPI_WRITE32( REG_SPIC_CTRLR1, BIT_NDF( 4 ) ); + + switch ( SpicBitMode ) + { + case SpicOneBitMode: + HAL_SPI_WRITE32( REG_SPIC_CTRLR0, + ( HAL_SPI_READ32( REG_SPIC_CTRLR0 ) & ( ~( BIT_CMD_CH( 3 ) | BIT_ADDR_CH( 3 ) | BIT_DATA_CH( + 3 ) ) ) ) ); + break; + + case SpicDualBitMode: + HAL_SPI_WRITE32( REG_SPIC_CTRLR0, + ( ( HAL_SPI_READ32( REG_SPIC_CTRLR0 ) & ( ~( BIT_CMD_CH( 3 ) | BIT_ADDR_CH( 3 ) | BIT_DATA_CH( + 3 ) ) ) ) | + ( BIT_ADDR_CH( 1 ) | BIT_DATA_CH( 1 ) ) ) ); + break; + + case SpicQuadBitMode: + HAL_SPI_WRITE32( REG_SPIC_CTRLR0, + ( ( HAL_SPI_READ32( REG_SPIC_CTRLR0 ) & ( ~( BIT_CMD_CH( 3 ) | BIT_ADDR_CH( 3 ) | BIT_DATA_CH( + 3 ) ) ) ) | + ( BIT_ADDR_CH( 2 ) | BIT_DATA_CH( 2 ) ) ) ); + break; + } +} + + +/** + * @brief SpicEraseFlashRefinedRtl8195A. + * + * @param NA + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION +VOID +SpicEraseFlashRefinedRtl8195A( VOID ) { SPIC_INIT_PARA SpicInitPara; - u32 CpuClkMode = (HAL_PERI_ON_READ32(REG_SYS_CLK_CTRL1) - >> BIT_SHIFT_PESOC_OCP_CPU_CK_SEL) & BIT_MASK_PESOC_OCP_CPU_CK_SEL; // v3 = (40000014 >> 4) & 7; - SpicLoadInitParaFromClockRtl8195A(CpuClkMode, 1, &SpicInitPara); - DBG_MISC_ERR("Init Baud Rate: 0x%x\n", SpicInitPara.BaudRate); - DBG_MISC_ERR("Init RD Dummy: 0x%x\n", SpicInitPara.RdDummyCyle); - DBG_MISC_ERR("Init Delay Line: 0x%x\n", SpicInitPara.DelayLine); - while (SpicGetFlashStatusRtl8195A(SpicInitPara) & 1); - while (!(SpicGetFlashStatusRtl8195A(SpicInitPara) & 2)) SpicTxCmdRtl8195A(FLASH_CMD_WREN, SpicInitPara); - DBG_MISC_ERR("Erase Cmd Set\n"); - SpicTxCmdRtl8195A(FLASH_CMD_CE, SpicInitPara); - while (SpicGetFlashStatusRtl8195A(SpicInitPara) & 2); // write enable latch + // Wait for flash busy done + SpicWaitWipDoneRefinedRtl8195A( SpicInitPara ); + + while( ( SpicGetFlashStatusRefinedRtl8195A( SpicInitPara ) & 0x02 ) == 0 ) + { + // Set flash_cmd: WREN to FIFO + //SpicTxCmdRtl8195A(FLASH_CMD_WREN, SpicInitPara); + SpicTxCmdWithDataRtl8195A( FLASH_CMD_WREN, 0, 0, SpicInitPara ); + } + + DBG_8195A( "Erase Cmd Set\n" ); + // Set flash_cmd: Chip_erase to FIFO + //SpicTxCmdRtl8195A(FLASH_CMD_CE, SpicInitPara); + SpicTxCmdWithDataRtl8195A( FLASH_CMD_CE, 0, 0, SpicInitPara ); + + // polling WEL + do + { + } + while( ( SpicGetFlashStatusRefinedRtl8195A( SpicInitPara ) & 0x02 ) != 0 ); } -//----- SpiFlashApp -void SpiFlashApp(u32 * parm) +/** + * @brief SpicSetFlashStatusRefinedRtl8195A. + * + * @param NA + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION +VOID +SpicSetFlashStatusRefinedRtl8195A +( + IN u32 data, + IN SPIC_INIT_PARA SpicInitPara +) +{ + u32 Info; + Info = HAL_SPI_READ32( REG_SPIC_ADDR_LENGTH ); + // Set flash_cmd: WREN to FIFO + //SpicTxCmdRtl8195A(FLASH_CMD_WREN, SpicInitPara); + SpicTxCmdWithDataRtl8195A( FLASH_CMD_WREN, 0, 0, SpicInitPara ); + // Disable SPI_FLASH + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + // set ctrlr0: TX mode + HAL_SPI_WRITE32( REG_SPIC_CTRLR0, + ( HAL_SPI_READ32( REG_SPIC_CTRLR0 ) & ( ~ BIT_TMOD( 3 ) ) ) ); + HAL_SPI_WRITE32( REG_SPIC_ADDR_LENGTH, BIT_ADDR_PHASE_LENGTH( 1 ) ); + // Set flash_cmd: WRSR to FIFO + HAL_SPI_WRITE8( REG_SPIC_DR0, BIT_DR0( FLASH_CMD_WRSR ) ); + // Set data FIFO + HAL_SPI_WRITE8( REG_SPIC_DR0, BIT_DR0( data ) ); + // Enable SPI_FLASH User Mode + HAL_SPI_WRITE32( REG_SPIC_SSIENR, BIT_SPIC_EN ); + // wait spic busy done + SpicWaitBusyDoneRtl8195A(); + + if( ( SpicInitParaAllClk[0][0].flashtype ) == FLASH_MICRON ) + SpicWaitOperationDoneRtl8195A( SpicInitPara ); + else + SpicWaitWipDoneRefinedRtl8195A( SpicInitPara ); + + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32( REG_SPIC_SSIENR, 0 ); + HAL_SPI_WRITE32( REG_SPIC_ADDR_LENGTH, Info ); + // wait flash busy done (wip=0) + SpicWaitWipDoneRefinedRtl8195A( SpicInitPara ); +} + + +/** + * @brief SpicWaitWipRtl8195A. + * + * @param NA + * + * @retval NA + */ + +HAL_FLASH_TEXT_SECTION +u32 +SpicWaitWipRtl8195A( + VOID +) { SPIC_INIT_PARA SpicInitPara; + /* Check for flash ready status */ + SpicWaitWipDoneRefinedRtl8195A( SpicInitPara ); + return _TRUE; +} - u32 CpuClkMode = (HAL_PERI_ON_READ32(REG_SYS_CLK_CTRL1) - >> BIT_SHIFT_PESOC_OCP_CPU_CK_SEL) & BIT_MASK_PESOC_OCP_CPU_CK_SEL; // v3 = (40000014 >> 4) & 7; - SpicLoadInitParaFromClockRtl8195A(CpuClkMode, 1, &SpicInitPara); - if (parm[0] == 1) + +/** + * @brief SpicSetFlashStatusRefinedRtl8195A. + * + * @param NA + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION +u32 +SpicOneBitCalibrationRtl8195A( + IN u8 SysCpuClk +) +{ + u32 DefRdDummyCycle = 0; + // set auto mode + SpicConfigAutoModeRtl8195A( SpicOneBitMode ); + /* MXIC spec */ + DefRdDummyCycle = 0; + + if ( !SpicCalibrationRtl8195A( SpicOneBitMode, DefRdDummyCycle ) ) { - DBG_MISC_ERR("Initial Spi Flash Controller\n"); - HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT_SOC_FLASH_EN); // 40000210 |= 0x10u; - HAL_PERI_ON_WRITE32(REG_PESOC_CLK_CTRL, HAL_PERI_ON_READ32(REG_PESOC_CLK_CTRL) | BIT_SOC_ACTCK_FLASH_EN); // 40000230 |= 0x100u; - HAL_PERI_ON_WRITE32(REG_PESOC_CLK_CTRL, HAL_PERI_ON_READ32(REG_PESOC_CLK_CTRL) | BIT_SOC_SLPCK_FLASH_EN); // 40000230 |= 0x200u; - HalPinCtrlRtl8195A(SPI_FLASH, 0, 1); - if (parm[1] == SpicDualBitMode) + return _FALSE; + } + +#if 0 + DBG_8195A( "@baud:%x\n", SpicInitParaAllClk[0][SysCpuClk].BaudRate ); + DBG_8195A( "@delay:%x\n", SpicInitParaAllClk[0][SysCpuClk].DelayLine ); + DBG_8195A( "@dummy:%x\n\n", SpicInitParaAllClk[0][SysCpuClk].RdDummyCyle ); +#endif + return _TRUE; +} + +/** + * @brief SpicDisableRtl8195A. + * Disable SPI Flash memory controller. + * @param NA + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION +VOID +SpicDisableRtl8195A( VOID ) +{ + SPI_FLASH_PIN_FCTRL( OFF ); +} + +#if SPIC_CALIBRATION_IN_NVM +/** + * @brief SpicNVMCalLoad. + * Load the SPI Flash Controller Calibration data from NVM + * @param NA + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION VOID +SpicNVMCalLoad( u8 BitMode, u8 CpuClk ) +{ + SPIC_INIT_PARA * pspci_para; + u32 spci_para; + u32 spci_para_inv; + u32 flash_offset; + // DBG_SPIF_INFO("SpicNVMCalLoad==> BitMode=%d CpuClk=%d\r\n", BitMode, CpuClk); + /* each Calibration parameters use 8 bytes, first 4-bytes are the calibration data, + 2nd 4-bytes are the validate data: ~(calibration data) */ + flash_offset = ( CpuClk * 8 ) + ( BitMode * CPU_CLK_TYPE_NO * 8 ); + spci_para = HAL_READ32( SPI_FLASH_BASE, ( FLASH_SPIC_PARA_BASE + flash_offset ) ); + + if ( spci_para != 0xFFFFFFFF ) + { + spci_para_inv = HAL_READ32( SPI_FLASH_BASE, ( FLASH_SPIC_PARA_BASE + flash_offset + 4 ) ); + + if ( 0xFFFFFFFF == ( spci_para ^ spci_para_inv ) ) { - DBG_MISC_ERR("Initial Spic Two bit mode\n"); - SpicInitRtl8195A(SpicInitPara.BaudRate, SpicDualBitMode); + pspci_para = ( SPIC_INIT_PARA * )&spci_para; + SpicInitParaAllClk[BitMode][CpuClk].BaudRate = pspci_para->BaudRate; + SpicInitParaAllClk[BitMode][CpuClk].RdDummyCyle = pspci_para->RdDummyCyle; + SpicInitParaAllClk[BitMode][CpuClk].DelayLine = pspci_para->DelayLine; + SpicInitParaAllClk[BitMode][CpuClk].Valid = pspci_para->Valid; + DBG_SPIF_INFO( "SpicNVMCalLoad: Calibration Loaded(BitMode %d, CPUClk %d): BaudRate=0x%x RdDummyCyle=0x%x DelayLine=0x%x\r\n", + BitMode, CpuClk, + SpicInitParaAllClk[BitMode][CpuClk].BaudRate, + SpicInitParaAllClk[BitMode][CpuClk].RdDummyCyle, + SpicInitParaAllClk[BitMode][CpuClk].DelayLine ); } - else if (parm[1] < SpicDualBitMode) + else { - DBG_MISC_ERR("Initial Spic One bit mode\n"); - SpicInitRtl8195A(SpicInitPara.BaudRate, SpicOneBitMode); - } - else if (parm[1] == SpicQuadBitMode) - { - DBG_MISC_ERR("Initial Spic Four bit mode\n"); - SpicInitRtl8195A(SpicInitPara.BaudRate, SpicQuadBitMode); + DBG_SPIF_WARN( "SpicNVMCalLoad: Data in Flash(@ 0x%x = 0x%x 0x%x) is Invalid\r\n", + ( FLASH_SPIC_PARA_BASE + flash_offset ), spci_para, spci_para_inv ); } } - else if (parm[0] == 2) + else { - DBG_MISC_ERR("Erase Flash Start\n"); - SpicEraseFlashRtl8195A(); - DBG_MISC_ERR("Erase Flash End\n"); + // DBG_SPIF_INFO("SpicNVMCalLoad: No Data in Flash(@ 0x%x)\r\n", flash_offset); } } -#endif - -//----- SpicRxCmdRefinedRtl8195A -VOID HAL_FLASH_TEXT_SECTION SpicRxCmdRefinedRtl8195A(IN u8 cmd, IN SPIC_INIT_PARA SpicInitPara) { - SPIC_INIT_PARA SpicInitParaa; - u32 CpuClkMode = (HAL_PERI_ON_READ32(REG_SYS_CLK_CTRL1) - >> BIT_SHIFT_PESOC_OCP_CPU_CK_SEL) & BIT_MASK_PESOC_OCP_CPU_CK_SEL; // v3 = (40000014 >> 4) & 7; - PSPIC_INIT_PARA pspicp = &SpicInitParaAllClk[0][CpuClkMode]; - if (!pspicp->Rsvd) { - SpicLoadInitParaFromClockRtl8195A(CpuClkMode, 1, &SpicInitParaa); - pspicp = &SpicInitParaa; - } - DBG_SPIF_INFO("%s(0x%x, 0x%x)\n", "SpicRxCmdRefinedRtl8195A", cmd, *((u32 *)(*pspicp))); - u32 AutoLengthSave = HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH); // v5 = 4000611C; - HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, - (HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH) & (~((BIT_MASK_RD_DUMMY_LENGTH) << BIT_SHIFT_RD_DUMMY_LENGTH))) | pspicp->RdDummyCyle); // 4000611C = v6->RdDummyCyle | (4000611C >> 16 << 16); - u32 BaudSave = HAL_SPI_READ32(REG_SPIC_BAUDR); // 40006014; - HAL_SPI_WRITE32(REG_SPIC_BAUDR, - ((HAL_SPI_READ32(REG_SPIC_BAUDR) >> 16) << 16) | pspicp->BaudRate); - u32 MemCtrlSave = HAL_PERI_ON_READ32(REG_PESOC_MEM_CTRL); // 40000300; - HAL_PERI_ON_WRITE32(REG_PESOC_MEM_CTRL, - (HAL_PERI_ON_READ32(REG_PESOC_MEM_CTRL) & 0xFFFFFF00) | pspicp->DelayLine); - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, - ((HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_ADDR_CH(3)|BIT_DATA_CH(3)|BIT_CTRL_TMOD(3)))) | BIT_CTRL_TMOD(3))); // SpicOneBitMode +..., 40006000 = 40006000 & 0xFFF0FCFF | 0x300; - HAL_PERI_ON_WRITE32(REG_SPIC_DR0, cmd); // 40006060 = v2; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(1)); // 40006008 = 1; - SpicWaitBusyDoneRtl8195A(); - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, - (HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH) >> 16 << 16) | AutoLengthSave); - HAL_SPI_WRITE32(REG_SPIC_BAUDR, - (HAL_SPI_READ32(REG_SPIC_BAUDR) >> 16 << 16) | BaudSave); - HAL_PERI_ON_WRITE32(REG_SPIC_CTRLR0, - (HAL_SPI_READ32(REG_SPIC_CTRLR0) & 0xFFFFFF00) | MemCtrlSave); -} - -//----- SpicInitRefinedRtl8195A -VOID HAL_FLASH_TEXT_SECTION SpicInitRefinedRtl8195A(IN u8 InitBaudRate, IN u8 SpicBitMode) { - PSPIC_INIT_PARA pspicp; - SPIC_INIT_PARA TmpSpicInitPara; - - TmpSpicInitPara.BaudRate = InitBaudRate; - TmpSpicInitPara.id[0] = SpicBitMode; - u32 CpuClkMode = (HAL_PERI_ON_READ32(REG_SYS_CLK_CTRL1) - >> BIT_SHIFT_PESOC_OCP_CPU_CK_SEL) & BIT_MASK_PESOC_OCP_CPU_CK_SEL; // v4 = (40000014 >> 4) & 7; - pspicp = &SpicInitParaAllClk[CpuClkMode]; - if (!pspicp->Rsvd) { - SpicLoadInitParaFromClockRtl8195A(CpuClkMode, 1, &TmpSpicInitPara); - pspicp = &TmpSpicInitPara; - } - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - HAL_SPI_WRITE32(REG_SPIC_BAUDR, InitBaudRate); - HAL_SPI_WRITE32(REG_SPIC_SER, BIT_CTRL_SER(1)); // 40006010 = 1; - HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, - (HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH) & (~((BIT_MASK_RD_DUMMY_LENGTH) << BIT_SHIFT_RD_DUMMY_LENGTH))) | pspicp->RdDummyCyle); // 4000611C = v6->RdDummyCyle | (4000611C >> 16 << 16); - HAL_PERI_ON_WRITE32(REG_PESOC_MEM_CTRL, - (HAL_PERI_ON_READ32(REG_PESOC_MEM_CTRL) & (~(BIT_MASK_PESOC_FLASH_DDL_CTRL << BIT_SHIFT_PESOC_FLASH_DDL_CTRL))) | pspicp->DelayLine); // 40000300 = v6->DelayLine | 40000300 & 0xFFFFFF00; - HAL_SPI_WRITE32(REG_SPIC_CTRLR1, BIT_CTRL_NDF(4)); //40006004 = 4; - u32 regdata = HAL_SPI_READ32(REG_SPIC_CTRLR0) - & (~((BIT_MASK_CMD_CH << BIT_SHIFT_CMD_CH) - | (BIT_MASK_DATA_CH << BIT_SHIFT_DATA_CH) - | (BIT_MASK_ADDR_CH << BIT_SHIFT_ADDR_CH))); // 0xFFC0FFFF; - if (SpicBitMode == SpicDualBitMode) { - regdata |= BIT_CTRL_ADDR_CH(1) | BIT_CTRL_DATA_CH(1); // 0x50000; // v7 = 40006000 & 0xFFC0FFFF | 0x50000; - } else if (SpicBitMode >= SpicDualBitMode) { - if (SpicBitMode != SpicQuadBitMode) return; - regdata |= BIT_CTRL_ADDR_CH(2) | BIT_CTRL_DATA_CH(2); // v7 = 40006000 & 0xFFC0FFFF | 0xA0000; - } - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, regdata); // 40006000 = v7; -} - -//----- SpicReadIDRtl8195A -void HAL_FLASH_TEXT_SECTION SpicReadIDRtl8195A(VOID) -//void SpicReadIDRtl8195A(SPIC_INIT_PARA SpicInitPara) +/** + * @brief SpicNVMCalLoadAll. + * Load the SPI Flash Controller Calibration data from NVM + * @param NA + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION VOID +SpicNVMCalLoadAll( void ) { - u16 flash_type; - u8 flashtype; - u32 flash_id; - u32 flash_density; - SPIC_INIT_PARA spic_para;// = SpicInitPara; -// memset(&spic_para, 0, sizeof(not_used)); -// spic_para = SpicInitPara; - DBG_SPIF_INFO("%s(0x%x)\n", "SpicReadIDRtl8195A", *((u32 *)spic_para)); - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - HAL_SPI_WRITE32(REG_SPIC_CTRLR1, BIT_CTRL_NDF(3)); //40006004 = 3; - SpicRxCmdRefinedRtl8195A(FLASH_CMD_RDID, (SPIC_INIT_PARA) spic_para); - flash_id = HAL_SPI_READ32(REG_SPIC_DR0); // 40006060; - flash_type = HAL_SPI_READ32(REG_SPIC_DR0) >> 8; // 40006060 >> 8; - flash_density = (HAL_SPI_READ32(REG_SPIC_DR0) >> 16) & 0xFF; // (40006060 >> 16) & 0xFF; - switch (flash_id) { - case 0x20: - flashtype = FLASH_MICRON; - break; - case 0xC2: - if (flash_density == 0x18) flashtype = FLASH_MXIC_4IO; - else flashtype = FLASH_MXIC; - break; - case 0xEF: - flashtype = FLASH_WINBOND; - break; - case 0x1C: - flashtype = FLASH_EON; - break; - default: - DBG_MISC_ERR("Invalid ID\n"); - flashtype = FLASH_OTHERS; - break; - } - int i, j; -LABEL_23: - for(i = 0; i < 3; i++){ - for(j = 0; j < 6; j++) { - SpicInitParaAllClk[i][j].id[0] = flash_id; - SpicInitParaAllClk[i][j].id[1] = flash_type; - SpicInitParaAllClk[i][j].id[2] = flash_density; - SpicInitParaAllClk[i][j].flashtype = flashtype; - }; - }; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; -} + u8 i, j; -//----- SpicConfigAutoModeRtl8195A -void HAL_FLASH_TEXT_SECTION SpicConfigAutoModeRtl8195A(enum _SPIC_BIT_MODE_ SpicBitMode) { - u32 regd; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - - HAL_SPI_WRITE32(REG_SPIC_VALID_CMD, HAL_SPI_READ32(REG_SPIC_VALID_CMD) & 0xFFFFFE01); // 40006120 &= 0xFFFFFE01; - if (SpicBitMode == SpicDualBitMode) { - HAL_SPI_WRITE32(REG_SPIC_WRITE_DUAL_ADDR_DATA, 0x0A2); // 400060FC = 162; - HAL_SPI_WRITE32(REG_SPIC_READ_DUAL_ADDR_DATA, 0x3B); // 400060E8 = 59; - regd = HAL_SPI_READ32(REG_SPIC_VALID_CMD) | BIT_RD_DUAL_I | BIT_WR_BLOCKING; // v1 = 40006120 | 0x202; - } else { - if (SpicBitMode != SpicQuadBitMode) return; - HAL_SPI_WRITE32(REG_SPIC_WRITE_QUAD_ADDR_DATA, 0x38); // 40006104 = 56; - HAL_SPI_WRITE32(REG_SPIC_READ_QUAD_ADDR_DATA, 0xEB); // 400060F0 = 235; - HAL_SPI_WRITE32(REG_SPIC_WRITE_QUAD_DATA, 0x32); // 40006100 = 50; - HAL_SPI_WRITE32(REG_SPIC_READ_QUAD_DATA, 0x6B); // 400060EC = 107; - if (SpicInitParaAllClk[0][0].flashtype == FLASH_MXIC_4IO) - regd = HAL_SPI_READ32(REG_SPIC_VALID_CMD) | BIT_RD_QUAD_O | BIT_WR_BLOCKING; // v1 = 40006120 | 0x208; - else - regd = HAL_SPI_READ32(REG_SPIC_VALID_CMD) | BIT_RD_QUAD_IO | BIT_WR_BLOCKING; // v1 = 40006120 | 0x210; - } - HAL_SPI_WRITE32(REG_SPIC_VALID_CMD, regd); // 40006120 = v1; -} - -#define SPI_FBLK 128 -//----- SpicUserReadRtl8195A -void HAL_FLASH_TEXT_SECTION SpicUserReadRtl8195A(uint32_t Length, uint32_t addr, uint8_t *data, int BitMode) { - - if(Length == 0 || data == NULL) return; - u32 cmd; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, - (HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_ADDR_CH(3)|BIT_DATA_CH(3)|BIT_CTRL_TMOD(3)))) | BIT_CTRL_TMOD(3)); // SpicOneBitMode +..., 40006000 = 40006000 & 0xFFF0FCFF | 0x300; - if (BitMode == SpicDualBitMode) { - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, - HAL_SPI_READ32(REG_SPIC_CTRLR0) | BIT_CTRL_FAST_RD(1)); // 40006000 |= 0x40000u; - cmd = FLASH_CMD_DREAD; - } - else cmd = FLASH_CMD_READ; - u32 faddr = addr; - u32 size = Length; - u32 blksize; - u8 * des = data; - HAL_SPI_WRITE32(REG_SPIC_ADDR_LENGTH, BIT_CTRL_ADDR_PHASE_LENGTH(3)); // 40006118 = 3; - HAL_SPI_WRITE32(REG_SPIC_SER, BIT_CTRL_SER(1)); // 40006010 = 1; - HAL_SPI_WRITE32(REG_SPIC_DR0, - ((u16)faddr >> 8 << 16) | (((faddr >> 16) & 0xFF) << 8) | (faddr << 24) | cmd); // 40006060 = ((u16)v7 >> 8 << 16) | (((v7 >> 16) & 0xFF) << 8) | (v7 << 24) | v8; - blksize = (u32)data & 3; - if(blksize) { - blksize = 4 - blksize; -#if DEBUGSOO > 4 - DiagPrintf("fr1:%p<-%p[%u]\n", des, faddr, blksize); -#endif - if(size < blksize) blksize = size; - HAL_SPI_WRITE32(REG_SPIC_CTRLR1, blksize); //40006004 = v9; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(1)); // 40006008 = 1; - size -= blksize; - faddr += blksize; - SpicWaitBusyDoneRtl8195A(); - uint32 data_buf = HAL_SPI_READ32(REG_SPIC_DR0); // SPI_FLASH_CTRL_BASE + REG_SPIC_DR0; - do { - *(uint8 *)des++ = data_buf; - data_buf >>= 8; - } while(--blksize); - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - } - while(size) { - if(size < SPI_FBLK) blksize = size; - else blksize = SPI_FBLK; -#if DEBUGSOO > 5 - DiagPrintf("fr2:%p<-%p[%u]\n", des, faddr, blksize); -#endif - HAL_SPI_WRITE32(REG_SPIC_CTRLR1, blksize); //40006004 = v4; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(1)); // 40006008 = 1; - size -= blksize; - faddr += blksize; - SpicWaitBusyDoneRtl8195A(); - uint32 *srcdw = (uint32 *)(SPI_FLASH_CTRL_BASE + REG_SPIC_DR0); - while(blksize >> 2) { - *((uint32 *)des) = *srcdw++; - des++; - blksize -= 4; - }; - if(blksize) { -#if DEBUGSOO > 4 - DiagPrintf("fr3:%p<-%p[%u]\n", des, faddr, blksize); -#endif - uint32 data_buf = *srcdw; - do { - *(uint8 *)des++ = data_buf; - data_buf >>= 8; - } while(--blksize); - break; - }; - }; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); // 40006008 = v4; - HAL_SPI_WRITE32(REG_SPIC_FLUSH_FIFO, BIT_FLUSH_FIFO); // 40006128 = 1; + for( i = 0; i < 3; i++ ) + { + for ( j = 0; j < CPU_CLK_TYPE_NO; j++ ) + { + SpicNVMCalLoad( i, j ); + } + } } -#define SPIC_RDBLK_SIZE 32 -//----- SpicUserReadFourByteRtl8195A -void HAL_FLASH_TEXT_SECTION SpicUserReadFourByteRtl8195A(uint32_t Length, uint32_t addr, uint32_t *data, int BitMode) { - u32 blklen = Length; - u32 faddr = addr; - u32 pdes = data; - u32 cmd; - u32 cnt; - - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); //40006008 = 0; - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, - ((HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_ADDR_CH(3)|BIT_DATA_CH(3)|BIT_CTRL_TMOD(3)))) | BIT_CTRL_TMOD(3))); // SpicOneBitMode +..., 40006000 = 40006000 & 0xFFF0FCFF | 0x300; - if (BitMode == SpicDualBitMode) { - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, - HAL_SPI_READ32(REG_SPIC_CTRLR0) | BIT_CTRL_FAST_RD(1)); // 40006000 |= 0x40000u; - cmd = FLASH_CMD_DREAD; // v8 = 59; - } else if (BitMode) { - if (SpicInitParaAllClk[0][0].flashtype == FLASH_MXIC_4IO) { - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, - HAL_SPI_READ32(REG_SPIC_CTRLR0) | BIT_CTRL_CK_MTIMES(1)); // 40006000 |= 0x80000u; - cmd = FLASH_CMD_QREAD; // cmd = 0x6B; - } else { - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, - HAL_SPI_READ32(REG_SPIC_CTRLR0) | BIT_CTRL_CK_MTIMES(1) | BIT_CTRL_CMD_CH(2)); // 40006000 |= 0xA0000u; - cmd = FLASH_CMD_4READ; // cmd = 0xEB; - } - } - else cmd = FLASH_CMD_READ; // cmd = 0x03; - if (blklen >= SPIC_RDBLK_SIZE) HAL_SPI_WRITE32(REG_SPIC_CTRLR1, BIT_CTRL_NDF(SPIC_RDBLK_SIZE)); //40006004 = 32; - if (blklen < SPIC_RDBLK_SIZE) HAL_SPI_WRITE32(REG_SPIC_CTRLR1, blklen); //40006004 = v4; - HAL_SPI_WRITE32(REG_SPIC_ADDR_LENGTH, BIT_CTRL_ADDR_PHASE_LENGTH(3)); // 40006118 = 3; - HAL_SPI_WRITE32(REG_SPIC_SER, BIT_CTRL_SER(1)); // 40006010 = 1; - HAL_SPI_WRITE32(REG_SPIC_DR0, - ((u16)addr >> 8 << 16) | (((addr >> 16) & 0xFF) << 8) | (addr << 24) | cmd); // 40006060 = ((u16)addr >> 8 << 16) | (v6 << 8) | (addr << 24) | v8; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(1)); //40006008 = 1; - SpicWaitBusyDoneRtl8195A(); - cnt = 0; - while (blklen) { - if (cnt == SPIC_RDBLK_SIZE) { - faddr += SPIC_RDBLK_SIZE; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); //40006008 = 0; - if (blklen >= SPIC_RDBLK_SIZE) HAL_SPI_WRITE32(REG_SPIC_CTRLR1, BIT_CTRL_NDF(SPIC_RDBLK_SIZE)); //40006004 = 32; - if (blklen < SPIC_RDBLK_SIZE) HAL_SPI_WRITE32(REG_SPIC_CTRLR1, blklen); //40006004 = v4; - HAL_SPI_WRITE32(REG_SPIC_DR0, - cmd | (faddr << 24) | (((faddr >> 16) & 0xFF) << 8) | ((u16)faddr >> 8 << 16)); // 40006060 = v8 | (v5 << 24) | (((v5 >> 16) & 0xFF) << 8) | ((u16)v5 >> 8 << 16); - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(1)); // 40006008 = 1; - SpicWaitBusyDoneRtl8195A(); - cnt = 0; - } - cnt += 4; - *pdes++ = HAL_SPI_READ32(REG_SPIC_DR0); // 40006060; - blklen -= 4; - } - HAL_SPI_WRITE32(REG_SPIC_FLUSH_FIFO, BIT_FLUSH_FIFO); // 40006128 = 1; -} - -//----- SpicGetExtendAddrRtl8195A -u8 HAL_FLASH_TEXT_SECTION SpicGetExtendAddrRtl8195A(SPIC_INIT_PARA SpicInitPara) { - SPIC_INIT_PARA SpicInitParaa = SpicInitPara; - DBG_SPIF_INFO("%s(0x%x)\n", "SpicGetExtendAddrRtl8195A", - SpicInitPara, SpicInitPara); - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - HAL_SPI_WRITE32(REG_SPIC_CTRLR1, BIT_CTRL_NDF(1)); //40006004 = 1; - SpicRxCmdRefinedRtl8195A(FLASH_CMD_REAR, SpicInitParaa); - u8 result = HAL_SPI_READ32(REG_SPIC_DR0); // 40006060; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - return result; -} - - -//----- SpicGetConfigRegRtl8195A -u8 HAL_FLASH_TEXT_SECTION SpicGetConfigRegRtl8195A(SPIC_INIT_PARA SpicInitPara) { - SPIC_INIT_PARA SpicInitParaa = SpicInitPara; - DBG_SPIF_INFO("%s(0x%x)\n", "SpicGetConfigRegRtl8195A", ((u32 *)SpicInitPara)[0]); - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - HAL_SPI_WRITE32(REG_SPIC_CTRLR1, BIT_CTRL_NDF(1)); //40006004 = 1; - SpicRxCmdRefinedRtl8195A(FLASH_CMD_RDCR, SpicInitParaa); - u8 result = HAL_SPI_READ32(REG_SPIC_DR0); // 40006060; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - return result; -} - -//----- SpicGetFlashStatusRefinedRtl8195A -u8 HAL_FLASH_TEXT_SECTION SpicGetFlashStatusRefinedRtl8195A(IN SPIC_INIT_PARA SpicInitPara) +/** + * @brief SpicNVMCalStore. + * Write the SPI Flash Controller Calibration data to NVM + * @param NA + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION VOID +SpicNVMCalStore( u8 BitMode, u8 CpuClk ) { - SPIC_INIT_PARA SpicInitParaa = SpicInitPara; + SPIC_INIT_PARA * pspci_para; + u32 spci_para; + u32 flash_offset; + SPIC_INIT_PARA SpicInitPara; + DBG_SPIF_INFO( "SpicNVMCalStore==> BitMode=%d CpuClk=%d\r\n", BitMode, CpuClk ); + /* each Calibration parameters use 8 bytes, first 4-bytes are the calibration data, + 2nd 4-bytes are the validate data: ~(calibration data) */ + flash_offset = ( CpuClk * 8 ) + ( BitMode * CPU_CLK_TYPE_NO * 8 ); + spci_para = HAL_READ32( SPI_FLASH_BASE, ( FLASH_SPIC_PARA_BASE + flash_offset ) ); - DBG_SPIF_INFO("%s(0x%x)\n", "SpicGetFlashStatusRefinedRtl8195A", ((u32 *)SpicInitPara)[0]); - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - HAL_SPI_WRITE32(REG_SPIC_CTRLR1, BIT_CTRL_NDF(1)); //40006004 = 1; - SpicRxCmdRefinedRtl8195A(FLASH_CMD_RDSR, SpicInitParaa); - u8 result = HAL_SPI_READ32(REG_SPIC_DR0); // 40006060; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - return result; -} - -//----- SpicWaitWipDoneRefinedRtl8195A -VOID HAL_FLASH_TEXT_SECTION SpicWaitWipDoneRefinedRtl8195A(IN SPIC_INIT_PARA SpicInitPara) -{ - SPIC_INIT_PARA SpicInitParaa = SpicInitPara; - - DBG_SPIF_INFO("%s(0x%x)\n", "SpicWaitWipDoneRefinedRtl8195A", ((u32 *)SpicInitParaa)[0]); - while (SpicGetFlashStatusRefinedRtl8195A(SpicInitParaa) & 1); -} - -//----- SpicTxCmdWithDataRtl8195A -VOID HAL_FLASH_TEXT_SECTION SpicTxCmdWithDataRtl8195A(IN u8 cmd, - IN u8 DataPhaseLen, IN u8* pData, IN SPIC_INIT_PARA SpicInitPara) -{ - SPIC_INIT_PARA SpicInitParaa = SpicInitPara; - u8 * pdes = pData; - int i; - - pdes = pData; - DBG_SPIF_INFO("%s(0x%x, 0x%x, 0x%x, 0x%x)\n", - "SpicTxCmdWithDataRtl8195A", cmd, DataPhaseLen, pData, ((u32 *)SpicInitParaa)[0]); - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - if (DataPhaseLen > 15) { - DBG_SPIF_WARN("SpicTxInstRtl8195A: Data Phase Leng too Big(%d)\n", DataPhaseLen); - DataPhaseLen = 15; - } - HAL_SPI_WRITE32(REG_SPIC_ADDR_LENGTH, DataPhaseLen); // 40006118 = v7; - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, - (HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_ADDR_CH(3)|BIT_DATA_CH(3)|BIT_CTRL_TMOD(3))))); // SpicOneBitMode: 40006000 &= 0xFFF0FCFF; - HAL_SPI_WRITE32(REG_SPIC_DR0, cmd); // 40006060 = v6; - for(i = 0; i < DataPhaseLen; i++) HAL_SPI_WRITE32(REG_SPIC_DR0, pdes[i]); // 40006060 = v9; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(1)); // 40006008 = 1; - SpicWaitBusyDoneRtl8195A(); - if (SpicInitParaAllClk[0][0].flashtype == 4) - SpicWaitOperationDoneRtl8195A(SpicInitParaa); - else - SpicWaitWipDoneRefinedRtl8195A(SpicInitParaa); -} - -//----- SpicGetFlashFlagRtl8195A -u8 HAL_FLASH_TEXT_SECTION SpicGetFlashFlagRtl8195A(SPIC_INIT_PARA SpicInitPara) { - u8 result; - SPIC_INIT_PARA SpicInitParaa = SpicInitPara; - DBG_SPIF_INFO("%s(0x%x)\n", "SpicGetFlashFlagRtl8195A", ((u32 *)SpicInitPara)[0]); - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - HAL_SPI_WRITE32(REG_SPIC_CTRLR1, BIT_CTRL_NDF(1)); //40006004 = 1; - SpicRxCmdRefinedRtl8195A(FLASH_CMD_RFSR, SpicInitParaa); - result = HAL_SPI_READ32(REG_SPIC_DR0); // 40006060; // HAL_SPI_WRITE32(REG_SPIC_DR0, v6); // 40006060 = - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - if (HAL_SPI_READ32(REG_SPIC_DR0) & 2) { // 40006060 & 2 ) - if (HAL_SPI_READ32(REG_SPIC_DR0) & 0x80) // SRWD (status register write protect) - DBG_SPIF_WARN("Attempts to Program / Erase Protected Area.\n"); - *(u32 *) &SpicInitParaa = *(u32 *) &SpicInitParaa.id[0]; // ??? - SpicTxCmdWithDataRtl8195A(FLASH_CMD_CFSR, 0, 0, SpicInitParaa); - } - return result; -} - -//----- SpicWaitOperationDoneRtl8195A -VOID HAL_FLASH_TEXT_SECTION SpicWaitOperationDoneRtl8195A(IN SPIC_INIT_PARA SpicInitPara) -//void SpicWaitOperationDoneRtl8195A(SPIC_INIT_PARA SpicInitPara, int a2) -{ - SPIC_INIT_PARA SpicInitParaa = SpicInitPara; - DBG_SPIF_INFO("%s(0x%x)\n", "SpicWaitOperationDoneRtl8195A",((u32 *)SpicInitPara)[0]); - while (!(SpicGetFlashFlagRtl8195A(SpicInitParaa) & 0x80)); -} - -//----- SpicDeepPowerDownFlashRtl8195A -VOID HAL_FLASH_TEXT_SECTION SpicDeepPowerDownFlashRtl8195A(SPIC_INIT_PARA SpicInitPara) -{ - if ((HAL_SYS_CTRL_READ32(REG_SYS_EFUSE_SYSCFG6) & BIT_SYS_CPU_CLK_SEL(2)) // v40000038 & 0x2000000 - && (((HAL_SYS_CTRL_READ32(REG_SYS_SYSTEM_CFG0) & 0xff) >> 4) > 1)) { // (u8) (400001F0 >> 4) > 1) - HAL_SYS_CTRL_WRITE32(REG_CPU_PERIPHERAL_CTRL, HAL_SYS_CTRL_READ32(REG_CPU_PERIPHERAL_CTRL) | BIT_SPI_FLSH_PIN_EN); // 400002C0 |= 1u; - SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); - DBG_MISC_ERR("Deep power down\n"); - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, - HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_ADDR_CH(3)|BIT_DATA_CH(3)|BIT_CTRL_TMOD(3)))); // SpicOneBitMode: 40006000 &= 0xFFF0FCFF; - HAL_SPI_WRITE32(REG_SPIC_DR0, 0xFFFFFFB9); // 40006060 = -71; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(1)); // 40006008 = 1; - HalDelayUs(20); - } -} - -//----- SpicUserProgramRtl8195A -VOID HAL_FLASH_TEXT_SECTION SpicUserProgramRtl8195A(IN u8 * data, IN SPIC_INIT_PARA SpicInitPara, - IN u32 addr, IN u32 * LengthInfo) -// void SpicUserProgramRtl8195A(uint8_t *data@, uint32_t addr@, u32 a3@, u32 a4@, SPIC_INIT_PARA SpicInitPara, uint32_t *LengthInfo) -{ - uint8_t *v6; // r5@1 - int v7; // r2@1 - u32 v8; // r1@1 - int v9; // r2@4 - uint32_t v10; // r10@10 - uint32_t v11; // r0@11 - int v12; // r1@11 - char *v13; // r0@11 - u32 v14; // r4@11 - char v15; // t1@12 - int v16; // r11@12 - u8 v17; // r1@18 - uint32_t v18; // r2@19 - int v19; // r0@21 - int v20; // r11@21 - int v21; // r9@27 - int v22; // r2@31 - int v23; // r1@31 - int v24; // r3@32 - int v25; // r3@34 - u32 v26; // r0@34 - int v27; // r2@39 - int v28; // r1@41 - int v29; // r4@41 - int v30; // t1@43 - int v31; // r0@44 -// int v32; // r2@46 - SPIC_INIT_PARA SpicInitParab; // [sp+0h] [bp-40h]@0 - SPIC_INIT_PARA SpicInitParaa; // [sp+8h] [bp-38h]@1 - uint32_t writeword; // [sp+10h] [bp-30h]@1 - uint32_t lastwriteword; // [sp+14h] [bp-2Ch]@1 - - SpicInitParaa = SpicInitPara; - v6 = data; - writeword = 0; - lastwriteword = 0; - v7 = (u8) addr; - v8 = **(u32 **) &SpicInitPara; - if ((u8) addr) { - if (v8 <= 0xFF && v8 + v7 <= 0xFF) - v9 = **(u32 **) &SpicInitPara; - else - v9 = 256 - v7; - } else if (v8 >= 0x100) { - v9 = 256; - } else { - v9 = **(u32 **) &SpicInitPara; - } - v10 = addr & 3; - **(u32 **) &SpicInitPara = v8 - v9; - if (addr & 3) { - v11 = addr & 3; - addr -= v10; - writeword = *(u32 *) (addr - 0x68000000); - v10 = 4 - v10; - v12 = (int) v6; - v13 = (char *) &writeword + v11 - 1; - v14 = v9; - do { - v15 = *(u8 *) v12++; - --v14; - (v13++)[1] = v15; - v16 = v12; - } while (v14 && (u8) (v9 - v14) < v10); - } else { - if ((u32) v9 > 3) - writeword = (data[2] << 16) | (data[1] << 8) | *data - | (data[3] << 24); - v16 = (int) data; - v14 = v9; - } - v17 = v14 & 3; - if (v14 & 3) { - v17 = (u8) v17; - v18 = addr + v14 - 0x68000000; - if (v10) - v18 = addr + v14 - 0x67FFFFFC; - v19 = 0; - lastwriteword = *(u32 *) (v18 - v17); - v20 = v16 + v14 - v17; - while ((u8) v19 < v17) { - *((u8 *) &lastwriteword + v19) = *(u8 *) (v20 + v19); - ++v19; - } - v16 = v20 + v17; - if (!v10 && v14 <= 3) { - v14 = 0; - writeword = lastwriteword; - } - } - v21 = HAL_SPI_READ32(REG_SPIC_ADDR_LENGTH); // 40006118 - *(u32 *) &SpicInitParab.BaudRate = *(u32 *) &SpicInitParaa.id[0]; - SpicTxCmdWithDataRtl8195A(FLASH_CMD_WREN, 0, 0, *(u32 *) &SpicInitParaa, SpicInitParab); - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - HAL_SPI_WRITE32(REG_SPIC_CTRLR0, - HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_CTRL_TMOD(3)))); // 40006000 &= 0xFFFFFCFF; - HAL_SPI_WRITE32(REG_SPIC_ADDR_LENGTH, BIT_CTRL_ADDR_PHASE_LENGTH(3)); // 40006118 = 3; - HAL_SPI_WRITE32(REG_SPIC_DR0, writeword); // 40006060 = writeword; - if (v10) v16 = (int) &v6[v10]; - else if (v14 > 3) { - v16 = (int) (v6 + 4); - v14 -= 4; - } - v22 = v16; - v23 = v16 + 4; - while (1) { - v24 = v22; - if (v14 <= 4) - break; - v14 -= 4; - if (v22 & 3) { - v25 = (*(u8 *) (v22 + 2) << 16) | (*(u8 *) (v22 + 1) << 8) - | *(u8 *) (v23 - 4) | (*(u8 *) (v22 + 3) << 24); - writeword = v25; - v26 = v14; - HAL_SPI_WRITE32(REG_SPIC_DR0, v25); // 40006060 = v25; - v24 = v23; - } else { - v24 = v23; - HAL_SPI_WRITE32(REG_SPIC_DR0, *(u32 *)(v23 - 4)); //40006060 = *(u32 *)(v23 - 4); - v26 = v14; - } - v22 += 4; - v23 += 4; - if (v22 == v16 + 24) - goto LABEL_39; - } - v26 = v14; -LABEL_39: - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(1)); // 40006008 = 1; - v27 = v24 + v26; - if (v24 & 3) { - while ((u32) (v27 - v24) > 3) { - v28 = (*(u8 *) (v24 + 2) << 16) | (*(u8 *) (v24 + 1) << 8); - v29 = *(u8 *) v24; - v24 += 4; - writeword = v28 | v29 | (*(u8 *) (v24 - 1) << 24); - HAL_SPI_WRITE32(REG_SPIC_DR0, writeword); // 40006060 = writeword; - } - } else { - while ((u32) (v27 - v24) > 3) { - v30 = *(u32 *) v24; - v24 += 4; - HAL_SPI_WRITE32(REG_SPIC_DR0, v30); // 40006060 = v30; - } - } - v31 = v26 & 3; - if (v31) - HAL_SPI_WRITE32(REG_SPIC_DR0, lastwriteword); // 40006060 = lastwriteword; - SpicWaitBusyDoneRtl8195A(v31); - if (SpicInitParaa.flashtype == 4) - SpicWaitOperationDoneRtl8195A(SpicInitParaa); - else - SpicWaitWipDoneRefinedRtl8195A(SpicInitParaa); - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0; - HAL_SPI_WRITE32(REG_SPIC_ADDR_LENGTH, v21); // 40006118 = v21; -} - -//----- SpicWaitWipRtl8195A -int HAL_FLASH_TEXT_SECTION SpicWaitWipRtl8195A(VOID) -//int SpicWaitWipRtl8195A(SPIC_INIT_PARA SpicInitPara) -{ - SPIC_INIT_PARA SpicInitPara; - SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); - return 1; -} - -//----- SpicTxFlashInstRtl8195A -void HAL_FLASH_TEXT_SECTION SpicTxFlashInstRtl8195A(uint8_t cmd, int DataPhaseLen, uint8_t *pData) { - uint8_t v3; // r8@1 - int v4; // r7@1 - uint8_t *v5; // r6@1 - int v6; // r2@5 - SPIC_INIT_PARA v7; // [sp+0h] [bp-28h]@0 - SPIC_INIT_PARA SpicInitPara; // [sp+8h] [bp-20h]@0 - - v3 = cmd; - v4 = DataPhaseLen; - v5 = pData; - SpicWaitWipDoneRefinedRtl8195A(SpicInitPara, (int) pData); - DBG_MISC_ERR(); - while (1) { - *(u32 *) &v7.BaudRate = *(u32 *) &SpicInitPara.id[0]; - if (SpicGetFlashStatusRefinedRtl8195A(SpicInitPara) & 2) - break; - SpicTxCmdWithDataRtl8195A(FLASH_CMD_WREN, 0, 0, *(u32 *) &SpicInitPara, v7); - } - SpicTxCmdWithDataRtl8195A(cmd, v4, v5, *(u32 *) &SpicInitPara, v7); - if (SpicInitParaAllClk[0][0].flashtype == 4) { - SpicWaitOperationDoneRtl8195A(SpicInitPara, v6); - } else if (SpicInitParaAllClk[0][0].flashtype == 5) { - SpicWaitWipDoneRefinedRtl8195A(SpicInitPara, v6); - } else { - while (SpicGetFlashStatusRefinedRtl8195A(SpicInitPara) & 2) ; - } -} - -//----- SpicEraseFlashRefinedRtl8195A -void HAL_FLASH_TEXT_SECTION SpicEraseFlashRefinedRtl8195A(void) { - SpicTxFlashInstRtl8195A(FLASH_CMD_CE, 0, 0); -} - -//----- SpicDieEraseFlashRtl8195A -VOID HAL_FLASH_TEXT_SECTION SpicDieEraseFlashRtl8195A(IN u32 Address) -{ - u8 Addr[4]; - Addr[0] = Address >> 16; - Addr[1] = Address >> 8; - Addr[2] = Address; - SpicTxFlashInstRtl8195A(FLASH_CMD_DE, 3, (uint8_t *) &Addr); -} - -//----- SpicBlockEraseFlashRtl8195A -VOID HAL_FLASH_TEXT_SECTION SpicBlockEraseFlashRtl8195A(IN u32 Address) -{ - u8 Addr[4]; - Addr[0] = Address >> 16; - Addr[1] = Address >> 8; - Addr[2] = Address; - SpicTxFlashInstRtl8195A(FLASH_CMD_BE, 3, (uint8_t *) &Addr); -} - -//----- SpicSectorEraseFlashRtl8195A -VOID HAL_FLASH_TEXT_SECTION SpicSectorEraseFlashRtl8195A(IN u32 Address) -//void SpicSectorEraseFlashRtl8195A(uint32_t Address, int a2, int a3) -{ - u8 Addr[4]; - Addr[0] = Address >> 16; - Addr[1] = Address >> 8; - Addr[2] = Address; - SpicTxFlashInstRtl8195A(FLASH_CMD_SE, 3, (uint8_t *) &Addr); -} - -//----- SpicSetExtendAddrRtl8195A -VOID HAL_FLASH_TEXT_SECTION SpicSetExtendAddrRtl8195A(IN u32 data, IN SPIC_INIT_PARA SpicInitPara) -{ - uint32_t dataa = data; - SpicTxFlashInstRtl8195A(0xC5u, 1, (uint8_t *) &dataa); -} - -//----- SpicSetFlashStatusRefinedRtl8195A -VOID HAL_FLASH_TEXT_SECTION SpicSetFlashStatusRefinedRtl8195A(IN u32 data, - IN SPIC_INIT_PARA SpicInitPara) -{ - int DataPhaseLen; - u32 Buf = data; - if (SpicInitParaAllClk[0][0].flashtype - 2 > 1) - DataPhaseLen = 1; - else - DataPhaseLen = 2; - SpicTxFlashInstRtl8195A(FLASH_CMD_WRSR, DataPhaseLen, (uint8_t *) &Buf); -} - -//----- SpicWriteProtectFlashRtl8195A -VOID HAL_FLASH_TEXT_SECTION SpicWriteProtectFlashRtl8195A(IN u32 Protect) -//void SpicWriteProtectFlashRtl8195A(__int64 Protect) -{ - SPIC_INIT_PARA SpicInitPara; - u32 x; - u8 v2 = SpicGetFlashStatusRefinedRtl8195A(Protect, SpicInitPara); - if (Protect) - x = v2 | 0x1C; - else - x = v2 & 0xE3; - SpicSetFlashStatusRefinedRtl8195A(x, SpicInitPara); -} - -//----- SpicDisableRtl8195A -VOID HAL_FLASH_TEXT_SECTION SpicDisableRtl8195A(VOID) { - HAL_SYS_CTRL_WRITE32(REG_CPU_PERIPHERAL_CTRL, HAL_SYS_CTRL_READ32(REG_CPU_PERIPHERAL_CTRL) & ~BIT_SPI_FLSH_PIN_EN); // 400002C0 &= 0xFFFFFFFE; -} - -//----- SpicNVMCalLoad -VOID SpicNVMCalLoad(u8 BitMode, u8 CpuClk) -//void SpicNVMCalLoad(int BitMode, int CpuClk) -{ - int v2; // r4@1 - int v3; // r8@1 - int v4; // r11@1 - int v5; // r7@1 - int v6; // r6@1 - int v7; // r2@4 - int v8; // r1@4 - int v9; // r2@6 - char *v10; // r4@6 - uint32_t spci_para; // [sp+Ch] [bp-2Ch]@4 - - v2 = CpuClk + 6 * BitMode; - v3 = 0x40006120; - v4 = 0x40006014; - v5 = BitMode; - v6 = CpuClk; - if (0x40006014 == 1) { - BitMode = HalGetCpuClk(BitMode, CpuClk); - if (BitMode == 166666666) { - 40006120 |= 0x202u; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, v4); // 40006008 = v4; - SpicWaitBusyDoneRtl8195A(); - } - } - v7 = *(u32 *) (8 * v2 - 0x67FF6F80); - v8 = v7 + 1; - spci_para = *(u32 *) (8 * v2 - 0x67FF6F80); - if (v7 != -1) { - if ((*(u32 *) (8 * v2 - 0x67FF6F7C) ^ v7) == -1) { - v9 = v6 + 6 * v5; - v10 = (char *) SpicInitParaAllClk + 8 * v9; - SpicInitParaAllClk[0][v9].BaudRate = spci_para; - v10[1] = BYTE1(spci_para); - v10[2] = BYTE2(spci_para); - v10[3] = BYTE3(spci_para); - v8 = ConfigDebugInfo; - BitMode = ConfigDebugInfo << 19; - DBG_SPIF_INFO("SpicNVMCalLoad: Calibration Loaded(BitMode %d, CPUClk %d): BaudRate=0x%x RdDummyCyle=0x%x DelayLine=0x%x\r\n", - v5, v6, SpicInitParaAllClk[0][v9].BaudRate, (u8)v10[1], - (u8)v10[2]); - } else { - v8 = ConfigDebugWarn << 19; - DBG_SPIF_WARN("SpicNVMCalLoad: Data in Flash(@ 0x%x = 0x%x 0x%x) is Invalid\r\n", - 8 * v2 + 36992); - } - } - if (40006014 == 1 && HalGetCpuClk(BitMode, v8) == 166666666) { - 40006120 = v3; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(1)); // 40006008 = 1; - } -} - -//----- SpicNVMCalLoadAll -VOID HAL_FLASH_TEXT_SECTION SpicNVMCalLoadAll(void) { - int v0; // r5@1 - int v1; // r4@2 - int v2; // r1@3 - - v0 = 0; - do { - v1 = 0; - do { - v2 = (u8) v1++; - SpicNVMCalLoad(v0, v2); - } while (v1 != 6); - v0 = (u8) (v0 + 1); - } while (v0 != 3); -} - -//----- SpicNVMCalStore -VOID HAL_FLASH_TEXT_SECTION SpicNVMCalStore(u8 BitMode, u8 CpuClk) -//void SpicNVMCalStore(int BitMode, int CpuClk, int a3) -{ - int v3; // r6@1 - int v4; // r5@1 - int v5; // r4@5 - int v6; // r8@5 - int v7; // r2@9 - int v8; // r3@16 - int v9; // r3@19 - int spci_para; // [sp+Ch] [bp-34h]@6 - SPIC_INIT_PARA SpicInitPara; // [sp+10h] [bp-30h]@0 - - v3 = BitMode; - v4 = CpuClk; - if (!SpicInitParaAllClk[0][CpuClk + 6 * BitMode].id[0]) - SpicReadIDRtl8195A(BitMode, CpuClk, a3); - DBG_SPIF_INFO("SpicNVMCalStore==> BitMode=%d CpuClk=%d\r\n", v3, - v4); - v5 = v4 + 6 * v3; - v6 = v5; - if (*(u32 *) (8 * v5 + 0x98009080) == -1) { - LOBYTE (spci_para) = SpicInitParaAllClk[0][v5].BaudRate; - BYTE1 (spci_para) = SpicInitParaAllClk[0][v6].RdDummyCyle; - BYTE2 (spci_para) = SpicInitParaAllClk[0][v6].DelayLine; - BYTE3 (spci_para) = SpicInitParaAllClk[0][v6]._anon_0.Rsvd; - *(u32 *) (8 * v5 + 0x98009080) = spci_para; - if (SpicInitParaAllClk[0][v6].flashtype == 4) - SpicWaitOperationDoneRtl8195A(SpicInitPara, spci_para); - else - SpicWaitWipDoneRefinedRtl8195A(SpicInitPara, spci_para); - *(u32 *) (8 * v5 + 0x98009084) = ~spci_para; - v7 = SpicInitParaAllClk[0][v4 + 6 * v3].flashtype; - if (v7 == 4) - SpicWaitOperationDoneRtl8195A(SpicInitPara, 4); - else - SpicWaitWipDoneRefinedRtl8195A(SpicInitPara, v7); - DBG_SPIF_INFO("SpicNVMCalStore(BitMode %d, CPUClk %d): Calibration Stored: BaudRate=0x%x RdDummyCyle=0x%x DelayLine=0x%x\r\n", - v3, v4, SpicInitParaAllClk[0][v4 + 6 * v3].BaudRate, - SpicInitParaAllClk[0][v4 + 6 * v3].RdDummyCyle, - SpicInitParaAllClk[0][v4 + 6 * v3].DelayLine); - if (*(u32 *) (8 * v5 + 0x98009080) != spci_para) { - v8 = *(u32 *) (8 * v5 + 0x98009080); - DBG_SPIF_ERR("SpicNVMCalStore Err(Offset=0x%x), Wr=0x%x Rd=0x%x \r\n", - 8 * v5); - } - if (*(u32 *) (8 * v5 + 0x98009084) != ~spci_para) { - v9 = *(u32 *) (8 * v5 + 0x98009084); - DBG_SPIF_ERR("SpicNVMCalStore Err(Offset=0x%x), Wr=0x%x Rd=0x%x \r\n", - v6 * 8 + 4); - } - } else DBG_SPIF_ERR("SpicNVMCalStore: The flash memory(@0x%x = 0x%x) is not able to be write, Erase it first!!\r\n", - v6 * 8 + 0x9080); -} - -//----- SpicCalibrationRtl8195A -int HAL_FLASH_TEXT_SECTION SpicCalibrationRtl8195A(int SpicBitMode, uint32_t DefRdDummyCycle) { - u32 Delay_start; // v6; // r4@8 - int v7; // r12@8 - int RdDummyCyle; // int v8; // r10@8 - u32 Delay_end; // signed int v9; // r8@8 - int xbaud; // signed int v10; // r7@8 - int v11; // r2@12 - int v12; // r9@12 - int v13; // r5@14 - int v14; // r6@14 - int v15; // r3@14 - u8 DelayLine; // v21; // r4@40 - u16 Baud; // int v25; // [sp+18h] [bp-40h]@8 - int BitMode; // [sp+1Ch] [bp-3Ch]@1 - int v28; // [sp+24h] [bp-34h]@12 - SPIC_INIT_PARA SpicInitPara; // [sp+28h] [bp-30h]@0 - char v30; // [sp+30h] [bp-28h]@6 - u8 CpuClkMode = (HAL_PERI_ON_READ32(REG_SYS_CLK_CTRL1) - >> BIT_SHIFT_PESOC_OCP_CPU_CK_SEL) & BIT_MASK_PESOC_OCP_CPU_CK_SEL; // v3 = (40000014 >> 4) & 7; - BitMode = SpicBitMode; - - // v3 = DefRdDummyCycle; - - PSPIC_INIT_PARA pspic_para = &SpicInitParaAllClk[SpicBitMode][CpuClkMode]; - - if (!pspic_para->Rsvd) SpicNVMCalLoad(SpicBitMode, CpuClkMode); -// v4 = CpuClkMode + 6 * BitMode; -// v5 = (char *) SpicInitParaAllClk + 8 * v4; - - if (!pspic_para->DelayLine) { - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(0)); // 40006008 = 0 - HAL_SPI_WRITE32(REG_SPIC_BAUDR, pspic_para->BaudRate); // 40006014 = (u8)v5[0] - HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, - (HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH) - & (~((BIT_MASK_RD_DUMMY_LENGTH) << BIT_SHIFT_RD_DUMMY_LENGTH))) - | pspic_para->RdDummyCyle); // 4000611C = (4000611C >> 16 << 16) | (u8)v5[1], - HAL_PERI_ON_WRITE32(REG_PESOC_MEM_CTRL, - (HAL_PERI_ON_READ32(REG_PESOC_MEM_CTRL) & BIT_MASK_PESOC_FLASH_DDL_CTRL << BIT_SHIFT_PESOC_FLASH_DDL_CTRL) - | pspic_para->DelayLine); // 40000300 = 40000300 & 0xFFFFFF00 | (u8)v5[2] - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(1));// 40006008 = 1, - SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); - } - if(!SpicCmpDataForCalibrationRtl8195A()) { - DBG_MISC_ERR("SPI calibration\n"); - Delay_start = 0; - v7 = 2 * DefRdDummyCycle; - Baud = 0; - RdDummyCyle = 0; - Delay_end = 0; - xbaud = 1; - while ( 1 ) - { - if ((xbaud == 1) && (!BitMode) && (!CpuClkMode)) - goto LABEL_35; - v11 = 0; - - HAL_SPI_WRITE32(REG_SPIC_BAUDR, xbaud); // 40006014 = v10; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(1)); // 40006008 = 1; - v28 = v7 + 20; - v12 = v7; -LABEL_13: - if ( v12 < (u32)v28 ) break; - if ( v11 ) { - DBG_MISC_ERR("Find the avaiable window\n"); - DBG_MISC_ERR("Baud:%x; auto_length:%x; Delay start:%x; Delay end:%x\n", Baud, RdDummyCyle, Delay_start, Delay_end); - HAL_SPI_WRITE32(REG_SPIC_BAUDR, Baud & 0xFFF); //40006014 = v25 & 0xFFF; - pspic_para->BaudRate = Baud; -// v20 = (char *)SpicInitParaAllClk + 8 * (CpuClkMode + 6 * BitMode); - HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, - (HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH) - & (~((BIT_MASK_RD_DUMMY_LENGTH) << BIT_SHIFT_RD_DUMMY_LENGTH))) - | RdDummyCyle); // 4000611C = (4000611C >> 16 << 16) | v8 - pspic_para->RdDummyCyle = RdDummyCyle; - pspic_para->DelayLine = (u32)(Delay_start + Delay_end) >> 1; - HAL_PERI_ON_WRITE32(REG_PESOC_MEM_CTRL, - (HAL_PERI_ON_READ32(REG_PESOC_MEM_CTRL) & BIT_MASK_PESOC_FLASH_DDL_CTRL << BIT_SHIFT_PESOC_FLASH_DDL_CTRL) - | pspic_para->DelayLine); // 40000300 = 40000300 & 0xFFFFFF00 | DelayLine - pspic_para->Rsvd = 1; - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(1)); // 40006008 = 1; - SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); - SpicNVMCalStore(BitMode, CpuClkMode); - return 1; - } -LABEL_35: - if (++xbaud == 5) return 0; - v7 += 2 * DefRdDummyCycle; - } - v13 = 0; - HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, - (HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH) - & (~((BIT_MASK_RD_DUMMY_LENGTH) << BIT_SHIFT_RD_DUMMY_LENGTH))) - | v12); // 4000611C = (4000611C >> 16 << 16) | v12, - HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_CTRL_SPIC_EN(1)); // 40006008 = 1; - v14 = 0; - v15 = 99; - while ( 1 ) - { - HAL_PERI_ON_WRITE32(REG_PESOC_MEM_CTRL, - (HAL_PERI_ON_READ32(REG_PESOC_MEM_CTRL) & BIT_MASK_PESOC_FLASH_DDL_CTRL << BIT_SHIFT_PESOC_FLASH_DDL_CTRL) - | v13); // 40000300 = 40000300 & 0xFFFFFF00 | v13 - if ( !SpicCmpDataForCalibrationRtl8195A() ) - { - if ((v14 == 1) && ((v11 == 1) || ((v13 - v15) > (u32)(Delay_end - Delay_start)))) - { - Baud = xbaud; - RdDummyCyle = v12; - Delay_end = v13; - Delay_start = v15; - } - v14 = 0; - goto LABEL_30; - } - if ( !v14 ) - { - v11++; - v15 = v13; - } - if ( v13 == 99 ) - { - if ( v11 == 1 ) - { - Baud = xbaud; -LABEL_23: - RdDummyCyle = v12; - Delay_end = 99; - Delay_start = v15; - goto LABEL_28; - } - if ( 99 - v15 > (u32)(Delay_end - Delay_start) ) - { - Baud = xbaud; - goto LABEL_23; - } - } -LABEL_28: - v14 = 1; -LABEL_30: - ++v13; - if ( v13 == 100 ) - { - ++v12; - goto LABEL_13; - } - } - } - return 1; -} - -//----- SpicFlashInitRtl8195A -extern BOOLEAN HAL_FLASH_TEXT_SECTION SpicFlashInitRtl8195A(u8 SpicBitMode) -{ - SPIC_INIT_PARA SpicInitPara; - u8 DefRdDummyCycle; - bool result; - *(u32 *) &SpicInitPara.BaudRate = 0; // = SpicBitMode ? -#if defined(E_CUT_ROM_DOMAIN) || (!defined(CONFIG_RELEASE_BUILD_LIBRARIES)) - *(u32 *) &SpicInitPara.id[0] = 0; -#endif - // v2 = SpicBitMode; - if (!SpicInitParaAllClk[0][0].id[0]) SpicReadIDRtl8195A(SpicInitPara); - SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); - switch(SpicBitMode) { - case SpicOneBitMode: - SpicConfigAutoModeRtl8195A(SpicOneBitMode); - DefRdDummyCycle = 0; - break; - case SpicDualBitMode: - SpicConfigAutoModeRtl8195A(SpicDualBitMode); - DefRdDummyCycle = 8; - break; - case SpicQuadBitMode: - SpicConfigAutoModeRtl8195A(SpicQuadBitMode); - if (SpicInitParaAllClk[0][0].flashtype == FLASH_EON) - DefRdDummyCycle = 6; - else - DefRdDummyCycle = 8; - break; - default: - DBG_MISC_ERR("No Support SPI Mode!\n"); - SpicConfigAutoModeRtl8195A(SpicOneBitMode); - DefRdDummyCycle = 0; - } - if (SpicCalibrationRtl8195A(SpicBitMode, DefRdDummyCycle)) { - result = 1; - } else { - DBG_MISC_ERR("SPI calibration fail and recover one bit mode\n"); - SpicLoadInitParaFromClockRtl8195A(0, 0, &SpicInitPara); - SpicInitRefinedRtl8195A(SpicInitPara.BaudRate, SpicOneBitMode); - SpicConfigAutoModeRtl8195A(SpicOneBitMode); - result = 0; - } - return result; -} - -//----- SpicOneBitCalibrationRtl8195A -u32 HAL_FLASH_TEXT_SECTION SpicOneBitCalibrationRtl8195A(IN u8 SysCpuClk) -{ - SpicConfigAutoModeRtl8195A(SpicOneBitMode); - u32 result = SpicCalibrationRtl8195A(SpicOneBitMode, 0); - if (result) result = 1; - return result; + if ( spci_para == 0xFFFFFFFF ) + { + // if (1) { + pspci_para = ( SPIC_INIT_PARA * )&spci_para; + pspci_para->BaudRate = SpicInitParaAllClk[BitMode][CpuClk].BaudRate; + pspci_para->RdDummyCyle = SpicInitParaAllClk[BitMode][CpuClk].RdDummyCyle; + pspci_para->DelayLine = SpicInitParaAllClk[BitMode][CpuClk].DelayLine; + pspci_para->Valid = SpicInitParaAllClk[BitMode][CpuClk].Valid; + HAL_WRITE32( SPI_FLASH_BASE, ( FLASH_SPIC_PARA_BASE + flash_offset ), spci_para ); + + if( ( SpicInitParaAllClk[BitMode][CpuClk].flashtype ) == FLASH_MICRON ) + SpicWaitOperationDoneRtl8195A( SpicInitPara ); + else + SpicWaitWipDoneRefinedRtl8195A( SpicInitPara ); + + HAL_WRITE32( SPI_FLASH_BASE, ( FLASH_SPIC_PARA_BASE + flash_offset + 4 ), ~spci_para ); + + if( ( SpicInitParaAllClk[BitMode][CpuClk].flashtype ) == FLASH_MICRON ) + SpicWaitOperationDoneRtl8195A( SpicInitPara ); + else + SpicWaitWipDoneRefinedRtl8195A( SpicInitPara ); + + DBG_SPIF_INFO( "SpicNVMCalStore(BitMode %d, CPUClk %d): Calibration Stored: BaudRate=0x%x RdDummyCyle=0x%x DelayLine=0x%x\r\n", + BitMode, CpuClk, + SpicInitParaAllClk[BitMode][CpuClk].BaudRate, + SpicInitParaAllClk[BitMode][CpuClk].RdDummyCyle, + SpicInitParaAllClk[BitMode][CpuClk].DelayLine ); + + // Read back to check + if ( HAL_READ32( SPI_FLASH_BASE, ( FLASH_SPIC_PARA_BASE + flash_offset ) ) != spci_para ) + { + DBG_SPIF_ERR( "SpicNVMCalStore Err(Offset=0x%x), Wr=0x%x Rd=0x%x \r\n", + flash_offset, spci_para, HAL_READ32( SPI_FLASH_BASE, ( FLASH_SPIC_PARA_BASE + flash_offset ) ) ); + } + + if ( HAL_READ32( SPI_FLASH_BASE, ( FLASH_SPIC_PARA_BASE + flash_offset + 4 ) ) != ~spci_para ) + { + DBG_SPIF_ERR( "SpicNVMCalStore Err(Offset=0x%x), Wr=0x%x Rd=0x%x \r\n", + flash_offset + 4, ~spci_para, HAL_READ32( SPI_FLASH_BASE, + ( FLASH_SPIC_PARA_BASE + flash_offset + 4 ) ) ); + } + } + else + { + // There is a parameter on the flash memory already + DBG_SPIF_ERR( "SpicNVMCalStore: The flash memory(@0x%x = 0x%x) is not able to be write, Erase it first!!\r\n", + ( FLASH_SPIC_PARA_BASE + flash_offset ), spci_para ); + } } +#endif // #if SPIC_CALIBRATION_IN_NVM