Add accelerated SPI program, update ecflash
This commit is contained in:
		
							
								
								
									
										2
									
								
								ecflash
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								ecflash
									
									
									
									
									
								
							 Submodule ecflash updated: 9ea915cef4...4f21f47e5a
									
								
							| @@ -208,6 +208,101 @@ int parallel_transaction(struct Parallel * port, uint8_t * data, int length, boo | |||||||
| #define parallel_read(P, D, L) parallel_transaction(P, D, L, true, false) | #define parallel_read(P, D, L) parallel_transaction(P, D, L, true, false) | ||||||
| #define parallel_write(P, D, L) parallel_transaction(P, D, L, false, false) | #define parallel_write(P, D, L) parallel_transaction(P, D, L, false, false) | ||||||
|  |  | ||||||
|  | static uint8_t ADDRESS_INDAR1 = 0x05; | ||||||
|  | static uint8_t ADDRESS_INDDR = 0x08; | ||||||
|  |  | ||||||
|  | static uint8_t ZERO = 0x00; | ||||||
|  | static uint8_t SPI_ENABLE = 0xFE; | ||||||
|  | static uint8_t SPI_DATA = 0xFD; | ||||||
|  |  | ||||||
|  | // Disable chip | ||||||
|  | int parallel_spi_reset(struct Parallel *port) { | ||||||
|  |     int res; | ||||||
|  |  | ||||||
|  |     res = parallel_set_address(port, &ADDRESS_INDAR1, 1); | ||||||
|  |     if (res < 0) return res; | ||||||
|  |      | ||||||
|  |     res = parallel_write(port, &SPI_ENABLE, 1); | ||||||
|  |     if (res < 0) return res; | ||||||
|  |  | ||||||
|  |     res = parallel_set_address(port, &ADDRESS_INDDR, 1); | ||||||
|  |     if (res < 0) return res; | ||||||
|  |  | ||||||
|  |     return parallel_write(port, &ZERO, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Enable chip and read or write data | ||||||
|  | int parallel_spi_transaction(struct Parallel *port, uint8_t * data, int length, bool read) { | ||||||
|  |     int res; | ||||||
|  |  | ||||||
|  |     res = parallel_set_address(port, &ADDRESS_INDAR1, 1); | ||||||
|  |     if (res < 0) return res; | ||||||
|  |      | ||||||
|  |     res = parallel_write(port, &SPI_DATA, 1); | ||||||
|  |     if (res < 0) return res; | ||||||
|  |  | ||||||
|  |     res = parallel_set_address(port, &ADDRESS_INDDR, 1); | ||||||
|  |     if (res < 0) return res; | ||||||
|  |  | ||||||
|  |     return parallel_transaction(port, data, length, read, false); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #define parallel_spi_read(P, D, L) parallel_spi_transaction(P, D, L, true) | ||||||
|  | #define parallel_spi_write(P, D, L) parallel_spi_transaction(P, D, L, false) | ||||||
|  |  | ||||||
|  | // "Hardware" accelerated SPI programming, requires ECINDARs to be set | ||||||
|  | int parallel_spi_program(struct Parallel * port, uint8_t * data, int length, bool initialized) { | ||||||
|  |     static uint8_t aai[6] = { 0xAD, 0, 0, 0, 0, 0 }; | ||||||
|  |     int res; | ||||||
|  |     int i; | ||||||
|  |     uint8_t status; | ||||||
|  |  | ||||||
|  |     for(i = 0; (i + 1) < length; i+=2) { | ||||||
|  |         // Disable chip to begin command | ||||||
|  |         res = parallel_spi_reset(port); | ||||||
|  |         if (res < 0) return res; | ||||||
|  |  | ||||||
|  |         if (!initialized) { | ||||||
|  |             // If not initialized, the start address must be sent | ||||||
|  |             aai[1] = 0; | ||||||
|  |             aai[2] = 0; | ||||||
|  |             aai[3] = 0; | ||||||
|  |  | ||||||
|  |             aai[4] = data[i]; | ||||||
|  |             aai[5] = data[i + 1]; | ||||||
|  |  | ||||||
|  |             res = parallel_spi_write(port, aai, 6); | ||||||
|  |             if (res < 0) return res; | ||||||
|  |  | ||||||
|  |             initialized = true; | ||||||
|  |         } else { | ||||||
|  |             aai[1] = data[i]; | ||||||
|  |             aai[2] = data[i + 1]; | ||||||
|  |  | ||||||
|  |             res = parallel_spi_write(port, aai, 3); | ||||||
|  |             if (res < 0) return res; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Wait for SPI busy flag to clear | ||||||
|  |         for (;;) { | ||||||
|  |             // Disable chip to begin command | ||||||
|  |             res = parallel_spi_reset(port); | ||||||
|  |             if (res < 0) return res; | ||||||
|  |  | ||||||
|  |             status = 0x05; | ||||||
|  |             res = parallel_spi_write(port, &status, 1); | ||||||
|  |             if (res < 0) return res; | ||||||
|  |  | ||||||
|  |             res = parallel_spi_read(port, &status, 1); | ||||||
|  |             if (res < 0) return res; | ||||||
|  |  | ||||||
|  |             if (!(status & 1)) break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return i; | ||||||
|  | } | ||||||
|  |  | ||||||
| int serial_transaction(uint8_t * data, int length, bool read) { | int serial_transaction(uint8_t * data, int length, bool read) { | ||||||
|     int i; |     int i; | ||||||
|     for (i = 0; i < length; i++) { |     for (i = 0; i < length; i++) { | ||||||
| @@ -234,17 +329,29 @@ int parallel_main(void) { | |||||||
|     char command; |     char command; | ||||||
|     int length; |     int length; | ||||||
|     int i; |     int i; | ||||||
|  |     uint8_t address; | ||||||
|  |     bool set_address = false; | ||||||
|  |     bool program_aai = false; | ||||||
|     for (;;) { |     for (;;) { | ||||||
|         // Read command and length |         // Read command and length | ||||||
|         res = serial_read(data, 3); |         res = serial_read(data, 2); | ||||||
|         if (res < 0) goto err; |         if (res < 0) goto err; | ||||||
|         // Command is a character |         // Command is a character | ||||||
|         command = (char)data[0]; |         command = (char)data[0]; | ||||||
|  |  | ||||||
|  |         // Special address prefix | ||||||
|  |         if (command == 'A') { | ||||||
|  |             // Prepare to set address on next parallel cycle | ||||||
|  |             address = data[1]; | ||||||
|  |             set_address = true; | ||||||
|  |             continue; | ||||||
|  |         } else if (command != 'P') { | ||||||
|  |             // End accelerated programming | ||||||
|  |             program_aai = false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         // Length is received data + 1 |         // Length is received data + 1 | ||||||
|         length = ( |         length = ((int)data[1]) + 1; | ||||||
|             ((int)data[1]) | |  | ||||||
|             (((int)data[2]) << 8) |  | ||||||
|         ) + 1; |  | ||||||
|         // Truncate length to size of data |         // Truncate length to size of data | ||||||
|         if (length > sizeof(data)) length = sizeof(data); |         if (length > sizeof(data)) length = sizeof(data); | ||||||
|  |  | ||||||
| @@ -253,10 +360,8 @@ int parallel_main(void) { | |||||||
|             case 'B': |             case 'B': | ||||||
|                 // Fill buffer size - 1 |                 // Fill buffer size - 1 | ||||||
|                 for (i = 0; i < length; i++) { |                 for (i = 0; i < length; i++) { | ||||||
|                     if (i < 2) { |                     if (i == 0) { | ||||||
|                         data[i] = (uint8_t)( |                         data[i] = (uint8_t)(sizeof(data) - 1); | ||||||
|                             (sizeof(data) - 1) >> (i * 8) |  | ||||||
|                         ); |  | ||||||
|                     } else { |                     } else { | ||||||
|                         data[i] = 0; |                         data[i] = 0; | ||||||
|                     } |                     } | ||||||
| @@ -280,20 +385,15 @@ int parallel_main(void) { | |||||||
|  |  | ||||||
|                 break; |                 break; | ||||||
|  |  | ||||||
|             // Set address |  | ||||||
|             case 'A': |  | ||||||
|                 // Read data from serial |  | ||||||
|                 res = serial_read(data, length); |  | ||||||
|                 if (res < 0) goto err; |  | ||||||
|  |  | ||||||
|                 // Write address to parallel |  | ||||||
|                 res = parallel_set_address(port, data, length); |  | ||||||
|                 if (res < 0) goto err; |  | ||||||
|  |  | ||||||
|                 break; |  | ||||||
|  |  | ||||||
|             // Read data |             // Read data | ||||||
|             case 'R': |             case 'R': | ||||||
|  |                 // Update parallel address if necessary | ||||||
|  |                 if (set_address) { | ||||||
|  |                     res = parallel_set_address(port, &address, 1); | ||||||
|  |                     if (res < 0) goto err; | ||||||
|  |                     set_address = false; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|                 // Read data from parallel |                 // Read data from parallel | ||||||
|                 res = parallel_read(port, data, length); |                 res = parallel_read(port, data, length); | ||||||
|                 if (res < 0) goto err; |                 if (res < 0) goto err; | ||||||
| @@ -304,23 +404,48 @@ int parallel_main(void) { | |||||||
|  |  | ||||||
|                 break; |                 break; | ||||||
|  |  | ||||||
|  |             // Accelerated program function | ||||||
|  |             case 'P': | ||||||
|  |                 // Read data from serial | ||||||
|  |                 res = serial_read(data, length); | ||||||
|  |                 if (res < 0) goto err; | ||||||
|  |  | ||||||
|  |                 // Run accelerated programming function | ||||||
|  |                 res = parallel_spi_program(port, data, length, program_aai); | ||||||
|  |                 if (res < 0) goto err; | ||||||
|  |                 program_aai = true; | ||||||
|  |  | ||||||
|  |                 // Send ACK of data length | ||||||
|  |                 data[0] = (uint8_t)(length - 1); | ||||||
|  |                 res = serial_write(data, 1); | ||||||
|  |                 if (res < 0) goto err; | ||||||
|  |  | ||||||
|  |                 break; | ||||||
|  |  | ||||||
|             // Write data |             // Write data | ||||||
|             case 'W': |             case 'W': | ||||||
|                 // Read data from serial |                 // Read data from serial | ||||||
|                 res = serial_read(data, length); |                 res = serial_read(data, length); | ||||||
|                 if (res < 0) goto err; |                 if (res < 0) goto err; | ||||||
|  |  | ||||||
|  |                 // Update parallel address if necessary | ||||||
|  |                 if (set_address) { | ||||||
|  |                     res = parallel_set_address(port, &address, 1); | ||||||
|  |                     if (res < 0) goto err; | ||||||
|  |                     set_address = false; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|                 // Write data to parallel |                 // Write data to parallel | ||||||
|                 res = parallel_write(port, data, length); |                 res = parallel_write(port, data, length); | ||||||
|                 if (res < 0) goto err; |                 if (res < 0) goto err; | ||||||
|  |  | ||||||
|  |                 // Send ACK of data length | ||||||
|  |                 data[0] = (uint8_t)(length - 1); | ||||||
|  |                 res = serial_write(data, 1); | ||||||
|  |                 if (res < 0) goto err; | ||||||
|  |  | ||||||
|                 break; |                 break; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // Send ACK |  | ||||||
|         data[0] = '\r'; |  | ||||||
|         res = serial_write(data, 1); |  | ||||||
|         if (res < 0) goto err; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
| err: | err: | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
| #include <common/debug.h> | #include <common/debug.h> | ||||||
|  |  | ||||||
| // Set the desired keymap here | // Set the desired keymap here | ||||||
| #include "keymap/jeremy.h" | #include "keymap/default.h" | ||||||
|  |  | ||||||
| uint16_t keymap(int output, int input, int layer) { | uint16_t keymap(int output, int input, int layer) { | ||||||
|     if (output < KM_OUT && input < KM_IN && layer < KM_LAY) { |     if (output < KM_OUT && input < KM_IN && layer < KM_LAY) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user