Update .clang-format and apply
Update .clang-format for LLVM 14.0, available on Ubuntu 22.04. There is still plenty that clang-format sucks at or does wrong, so either add some more blocks to disable it, or just put up with it. Signed-off-by: Tim Crawford <tcrawford@system76.com>
This commit is contained in:
		
				
					committed by
					
						 Jeremy Soller
						Jeremy Soller
					
				
			
			
				
	
			
			
			
						parent
						
							c3267fc4ad
						
					
				
				
					commit
					e032c5f0f2
				
			| @@ -1,22 +1,25 @@ | ||||
| # https://releases.llvm.org/10.0.0/tools/clang/docs/ClangFormatStyleOptions.html | ||||
| # https://releases.llvm.org/14.0.0/tools/clang/docs/ClangFormatStyleOptions.html | ||||
| # LLVM 14 used to support Ubuntu 22.04 LTS. | ||||
| --- | ||||
| Language: Cpp | ||||
| AccessModifierOffset: -4 | ||||
| AlignAfterOpenBracket: AlwaysBreak | ||||
| AlignAfterOpenBracket: BlockIndent | ||||
| AlignConsecutiveAssignments: false | ||||
| AlignConsecutiveDeclarations: false | ||||
| AlignConsecutiveMacros: true | ||||
| AlignConsecutiveBitFields: None | ||||
| AlignConsecutiveDeclarations: None | ||||
| AlignConsecutiveMacros: false | ||||
| AlignEscapedNewlines: DontAlign | ||||
| AlignOperands: true | ||||
| AlignOperands: DontAlign | ||||
| AlignTrailingComments: false | ||||
| AllowAllArgumentsOnNextLine: true | ||||
| AllowAllConstructorInitializersOnNextLine: true | ||||
| AllowAllArgumentsOnNextLine: false | ||||
| AllowAllConstructorInitializersOnNextLine: false | ||||
| AllowAllParametersOfDeclarationOnNextLine: false | ||||
| AllowShortBlocksOnASingleLine: Empty | ||||
| AllowShortCaseLabelsOnASingleLine: false | ||||
| AllowShortFunctionsOnASingleLine: Inline | ||||
| AllowShortEnumsOnASingleLine: false | ||||
| AllowShortFunctionsOnASingleLine: Empty | ||||
| AllowShortIfStatementsOnASingleLine: Never | ||||
| AllowShortLambdasOnASingleLine: All | ||||
| AllowShortLambdasOnASingleLine: Empty | ||||
| AllowShortLoopsOnASingleLine: false | ||||
| AlwaysBreakAfterReturnType: None | ||||
| AlwaysBreakBeforeMultilineStrings: false | ||||
| @@ -26,42 +29,45 @@ BinPackParameters: false | ||||
| BraceWrapping: | ||||
|   AfterCaseLabel: false | ||||
|   AfterClass: true | ||||
|   AfterControlStatement: false | ||||
|   AfterControlStatement: Never | ||||
|   AfterEnum: false | ||||
|   AfterFunction: false | ||||
|   AfterNamespace: true | ||||
|   AfterNamespace: false | ||||
|   AfterObjCDeclaration: false | ||||
|   AfterStruct: false | ||||
|   AfterUnion: false | ||||
|   AfterExternBlock: false | ||||
|   BeforeCatch: false | ||||
|   BeforeElse: false | ||||
|   BeforeLambdaBody: false | ||||
|   BeforeWhile: false | ||||
|   IndentBraces: false | ||||
|   SplitEmptyFunction: false | ||||
|   SplitEmptyRecord: false | ||||
|   SplitEmptyNamespace: false | ||||
| BreakAfterJavaFieldAnnotations: false | ||||
| BreakAfterJavaFieldAnnotations: true | ||||
| BreakBeforeBinaryOperators: None | ||||
| BreakBeforeBraces: Custom | ||||
| BreakBeforeTernaryOperators: false | ||||
| BreakBeforeTernaryOperators: true | ||||
| BreakConstructorInitializers: AfterColon | ||||
| BreakConstructorInitializersBeforeComma: false | ||||
| BreakInheritanceList: AfterColon | ||||
| BreakStringLiterals: false | ||||
| ColumnLimit: 96 | ||||
| ColumnLimit: 100 | ||||
| CommentPragmas: '^ IWYU pragma:' | ||||
| CompactNamespaces: false | ||||
| ConstructorInitializerAllOnOneLineOrOnePerLine: false | ||||
| ConstructorInitializerAllOnOneLineOrOnePerLine: true | ||||
| ConstructorInitializerIndentWidth: 4 | ||||
| ContinuationIndentWidth: 4 | ||||
| Cpp11BracedListStyle: false | ||||
| DeriveLineEnding: false | ||||
| DerivePointerAlignment: false | ||||
| DisableFormat: false | ||||
| ExperimentalAutoDetectBinPacking: true | ||||
| ExperimentalAutoDetectBinPacking: false | ||||
| FixNamespaceComments: false | ||||
| ForEachMacros: | ||||
|   - foreach | ||||
| IncludeBlocks: Preserve | ||||
|   - 'foreach' | ||||
| IncludeBlocks: Regroup | ||||
| IncludeCategories: | ||||
|   - Regex: '^"(llvm|llvm-c|clang|clang-c)/' | ||||
|     Priority: 2 | ||||
| @@ -72,14 +78,17 @@ IncludeCategories: | ||||
|   - Regex: '.*' | ||||
|     Priority: 1 | ||||
|     SortPriority: 0 | ||||
| IncludeIsMainRegex: '(Test)?$' | ||||
| IncludeIsMainRegex: '(_test)?$' | ||||
| IncludeIsMainSourceRegex: '' | ||||
| IndentCaseLabels: true | ||||
| IndentCaseBlocks: true | ||||
| IndentCaseLabels: false | ||||
| IndentExternBlock: NoIndent | ||||
| IndentGotoLabels: false | ||||
| IndentPPDirectives: BeforeHash | ||||
| IndentPPDirectives: None | ||||
| IndentWidth: 4 | ||||
| IndentWrappedFunctionNames: false | ||||
| JavaScriptQuotes: Leave | ||||
| InsertTrailingCommas: Wrapped | ||||
| JavaScriptQuotes: Double | ||||
| JavaScriptWrapImports: true | ||||
| KeepEmptyLinesAtTheStartOfBlocks: false | ||||
| MacroBlockBegin: '' | ||||
| @@ -88,30 +97,29 @@ MaxEmptyLinesToKeep: 1 | ||||
| NamespaceIndentation: None | ||||
| ObjCBinPackProtocolList: Auto | ||||
| ObjCBlockIndentWidth: 4 | ||||
| ObjCBreakBeforeNestedBlockParam: true | ||||
| ObjCSpaceAfterProperty: true | ||||
| ObjCSpaceBeforeProtocolList: true | ||||
|  | ||||
| PenaltyBreakAssignment: 10 | ||||
| PenaltyBreakBeforeFirstCallParameter: 10 | ||||
| PenaltyBreakComment: 100 | ||||
| PenaltyBreakFirstLessLess: 5 | ||||
| PenaltyBreakString: 100 | ||||
| ObjCSpaceBeforeProtocolList: false | ||||
| PenaltyBreakAssignment: 1000 | ||||
| PenaltyBreakBeforeFirstCallParameter: 19 | ||||
| PenaltyBreakComment: 300 | ||||
| PenaltyBreakFirstLessLess: 120 | ||||
| PenaltyBreakString: 1000 | ||||
| PenaltyBreakTemplateDeclaration: 10 | ||||
| PenaltyExcessCharacter: 5 | ||||
| PenaltyReturnTypeOnItsOwnLine: 100 | ||||
|  | ||||
| PointerAlignment: Middle | ||||
| PenaltyExcessCharacter: 1000000 | ||||
| PenaltyReturnTypeOnItsOwnLine: 1000 | ||||
| PointerAlignment: Right | ||||
| ReflowComments: false | ||||
| SortIncludes: true | ||||
| SortIncludes: false | ||||
| SortUsingDeclarations: true | ||||
| SpaceAfterCStyleCast: false | ||||
| SpaceAfterLogicalNot: false | ||||
| SpaceAfterTemplateKeyword: true | ||||
| SpaceAfterTemplateKeyword: false | ||||
| SpaceBeforeAssignmentOperators: true | ||||
| SpaceBeforeCpp11BracedList: false | ||||
| SpaceBeforeCtorInitializerColon: true | ||||
| SpaceBeforeInheritanceColon: true | ||||
| SpaceBeforeParens: ControlStatements | ||||
| SpaceBeforeParens: ControlStatementsExceptForEachMacros | ||||
| SpaceBeforeRangeBasedForLoopColon: true | ||||
| SpaceBeforeSquareBrackets: false | ||||
| SpaceInEmptyBlock: false | ||||
| @@ -120,14 +128,14 @@ SpacesBeforeTrailingComments: 1 | ||||
| SpacesInAngles: false | ||||
| SpacesInCStyleCastParentheses: false | ||||
| SpacesInConditionalStatement: false | ||||
| SpacesInContainerLiterals: true | ||||
| SpacesInContainerLiterals: false | ||||
| SpacesInParentheses: false | ||||
| SpacesInSquareBrackets: false | ||||
| Standard: Latest | ||||
| StatementMacros: | ||||
|   - ARRAY_SIZE | ||||
|   - xstr | ||||
| TabWidth: 4 | ||||
| UseCRLF: false | ||||
| UseTab: Never | ||||
| WhitespaceSensitiveMacros: | ||||
|   - 'STRINGIZE' | ||||
| ... | ||||
|   | ||||
| @@ -9,13 +9,11 @@ void delay_ticks(uint16_t ticks); | ||||
|  | ||||
| // 1 us * 9.2 MHz / 12 is 69/90 | ||||
| // Warning: this will round to the nearest tick | ||||
| #define delay_us(X) \ | ||||
|     delay_ticks((uint16_t)((((uint32_t)(X)) * 69UL + 89UL) / 90UL)); | ||||
| #define delay_us(X) delay_ticks((uint16_t)((((uint32_t)(X)) * 69UL + 89UL) / 90UL)); | ||||
|  | ||||
| // 1 ns * 9.2 MHz / 12 is 69/90000 | ||||
| // Warning: this will round to the nearest tick | ||||
| #define delay_ns(X) \ | ||||
|     delay_ticks((uint16_t)((((uint32_t)(X)) * 69UL + 89999UL) / 90000UL)); | ||||
| #define delay_ns(X) delay_ticks((uint16_t)((((uint32_t)(X)) * 69UL + 89999UL) / 90000UL)); | ||||
|  | ||||
| void delay_ms(uint8_t ms); | ||||
|  | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  | ||||
| #include <arch/gpio.h> | ||||
|  | ||||
| bool gpio_get_dir(struct Gpio * gpio) { | ||||
| bool gpio_get_dir(struct Gpio *gpio) { | ||||
|     if (*gpio->ddr & gpio->value) { | ||||
|         return true; | ||||
|     } else { | ||||
| @@ -10,7 +10,7 @@ bool gpio_get_dir(struct Gpio * gpio) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| void gpio_set_dir(struct Gpio * gpio, bool value) { | ||||
| void gpio_set_dir(struct Gpio *gpio, bool value) { | ||||
|     if (value) { | ||||
|         *gpio->ddr |= gpio->value; | ||||
|     } else { | ||||
| @@ -18,7 +18,7 @@ void gpio_set_dir(struct Gpio * gpio, bool value) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| bool gpio_get(struct Gpio * gpio) { | ||||
| bool gpio_get(struct Gpio *gpio) { | ||||
|     if (*gpio->pin & gpio->value) { | ||||
|         return true; | ||||
|     } else { | ||||
| @@ -26,7 +26,7 @@ bool gpio_get(struct Gpio * gpio) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| void gpio_set(struct Gpio * gpio, bool value) { | ||||
| void gpio_set(struct Gpio *gpio, bool value) { | ||||
|     if (value) { | ||||
|         *gpio->port |= gpio->value; | ||||
|     } else { | ||||
|   | ||||
| @@ -8,9 +8,9 @@ | ||||
| #include <common/i2c.h> | ||||
| #include <common/macro.h> | ||||
|  | ||||
| #define TIMEOUT (F_CPU/1000) | ||||
| #define TIMEOUT (F_CPU / 1000) | ||||
|  | ||||
| int16_t i2c_start(struct I2C * i2c, uint8_t addr, bool read) { | ||||
| int16_t i2c_start(struct I2C *i2c, uint8_t addr, bool read) { | ||||
|     uint32_t count; | ||||
|  | ||||
|     // reset TWI control register | ||||
| @@ -19,11 +19,14 @@ int16_t i2c_start(struct I2C * i2c, uint8_t addr, bool read) { | ||||
|     TWCR = BIT(TWINT) | BIT(TWSTA) | BIT(TWEN); | ||||
|     // wait for end of transmission | ||||
|     count = TIMEOUT; | ||||
|     while(!(TWCR & BIT(TWINT)) && count > 0) count -= 1; | ||||
|     if (count == 0) return -1; | ||||
|     while (!(TWCR & BIT(TWINT)) && count > 0) | ||||
|         count -= 1; | ||||
|     if (count == 0) | ||||
|         return -1; | ||||
|  | ||||
|     // check if the start condition was successfully transmitted | ||||
|     if((TWSR & 0xF8) != TW_START) return -1; | ||||
|     if ((TWSR & 0xF8) != TW_START) | ||||
|         return -1; | ||||
|  | ||||
|     // load slave addr into data register | ||||
|     TWDR = ((addr << 1) | read); | ||||
| @@ -31,22 +34,25 @@ int16_t i2c_start(struct I2C * i2c, uint8_t addr, bool read) { | ||||
|     TWCR = BIT(TWINT) | BIT(TWEN); | ||||
|     // wait for end of transmission | ||||
|     count = TIMEOUT; | ||||
|     while(!(TWCR & BIT(TWINT)) && count > 0) count -= 1; | ||||
|     if (count == 0) return -1; | ||||
|     while (!(TWCR & BIT(TWINT)) && count > 0) | ||||
|         count -= 1; | ||||
|     if (count == 0) | ||||
|         return -1; | ||||
|  | ||||
|     // check if the device has acknowledged the READ / WRITE mode | ||||
|     uint8_t twst = TW_STATUS & 0xF8; | ||||
|     if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) return -1; | ||||
|     if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) | ||||
|         return -1; | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| void i2c_stop(struct I2C * i2c) { | ||||
| void i2c_stop(struct I2C *i2c) { | ||||
|     // transmit STOP condition | ||||
|     TWCR = BIT(TWINT) | BIT(TWEN) | BIT(TWSTO); | ||||
| } | ||||
|  | ||||
| int16_t i2c_write(struct I2C * i2c, uint8_t * data, uint16_t length) { | ||||
| int16_t i2c_write(struct I2C *i2c, uint8_t *data, uint16_t length) { | ||||
|     uint16_t i; | ||||
|     for (i = 0; i < length; i++) { | ||||
|         // load data into data register | ||||
| @@ -55,17 +61,20 @@ int16_t i2c_write(struct I2C * i2c, uint8_t * data, uint16_t length) { | ||||
|         TWCR = BIT(TWINT) | BIT(TWEN); | ||||
|         // wait for end of transmission | ||||
|         uint32_t count = TIMEOUT; | ||||
|         while(!(TWCR & BIT(TWINT)) && count > 0) count -= 1; | ||||
|         while (!(TWCR & BIT(TWINT)) && count > 0) | ||||
|             count -= 1; | ||||
|         // timed out | ||||
|         if (count == 0) return -1; | ||||
|         if (count == 0) | ||||
|             return -1; | ||||
|         // failed to receive ack | ||||
|         if((TWSR & 0xF8) != TW_MT_DATA_ACK) return -1; | ||||
|         if ((TWSR & 0xF8) != TW_MT_DATA_ACK) | ||||
|             return -1; | ||||
|     } | ||||
|  | ||||
|     return i; | ||||
| } | ||||
|  | ||||
| int16_t i2c_read(struct I2C * i2c, uint8_t * data, uint16_t length) { | ||||
| int16_t i2c_read(struct I2C *i2c, uint8_t *data, uint16_t length) { | ||||
|     uint16_t i; | ||||
|     for (i = 0; i < length; i++) { | ||||
|         if ((i + 1) < length) { | ||||
| @@ -77,8 +86,10 @@ int16_t i2c_read(struct I2C * i2c, uint8_t * data, uint16_t length) { | ||||
|         } | ||||
|         // wait for end of transmission | ||||
|         uint32_t count = TIMEOUT; | ||||
|         while(!(TWCR & BIT(TWINT)) && count > 0) count -= 1; | ||||
|         if (count == 0) return -1; | ||||
|         while (!(TWCR & BIT(TWINT)) && count > 0) | ||||
|             count -= 1; | ||||
|         if (count == 0) | ||||
|             return -1; | ||||
|         // return received data from TWDR | ||||
|         data[i] = TWDR; | ||||
|     } | ||||
|   | ||||
| @@ -11,11 +11,16 @@ | ||||
| #include <arch/i2c_slave.h> | ||||
| #include <common/macro.h> | ||||
|  | ||||
| static void (* volatile i2c_slave_new_cb)() = NULL; | ||||
| static void (* volatile i2c_slave_recv_cb)(uint8_t) = NULL; | ||||
| static uint8_t (* volatile i2c_slave_send_cb)() = NULL; | ||||
| static void (*volatile i2c_slave_new_cb)() = NULL; | ||||
| static void (*volatile i2c_slave_recv_cb)(uint8_t) = NULL; | ||||
| static uint8_t (*volatile i2c_slave_send_cb)() = NULL; | ||||
|  | ||||
| void i2c_slave_init(uint8_t address, void (*new_cb)(), void (*recv_cb)(uint8_t), uint8_t (*send_cb)()){ | ||||
| void i2c_slave_init( | ||||
|     uint8_t address, | ||||
|     void (*new_cb)(), | ||||
|     void (*recv_cb)(uint8_t), | ||||
|     uint8_t (*send_cb)() | ||||
| ) { | ||||
|     // ensure correct behavior by stopping before changing callbacks or address | ||||
|     i2c_slave_stop(); | ||||
|  | ||||
| @@ -35,7 +40,7 @@ void i2c_slave_init(uint8_t address, void (*new_cb)(), void (*recv_cb)(uint8_t), | ||||
|     sei(); | ||||
| } | ||||
|  | ||||
| void i2c_slave_stop(){ | ||||
| void i2c_slave_stop() { | ||||
|     // clear interrupts | ||||
|     cli(); | ||||
|  | ||||
| @@ -54,7 +59,7 @@ void i2c_slave_stop(){ | ||||
|  | ||||
| ISR(TWI_vect) { | ||||
|     uint8_t status = TW_STATUS; | ||||
|     switch(status) { | ||||
|     switch (status) { | ||||
|     case TW_SR_SLA_ACK: | ||||
|         // master has started a new transaction, call the new callback | ||||
|         if (i2c_slave_new_cb != NULL) { | ||||
| @@ -64,7 +69,7 @@ ISR(TWI_vect) { | ||||
|         break; | ||||
|     case TW_SR_DATA_ACK: | ||||
|         // received data from master, call the receive callback | ||||
|         if(i2c_slave_send_cb != NULL){ | ||||
|         if (i2c_slave_send_cb != NULL) { | ||||
|             i2c_slave_recv_cb(TWDR); | ||||
|         } | ||||
|         TWCR = BIT(TWIE) | BIT(TWINT) | BIT(TWEA) | BIT(TWEN); | ||||
| @@ -72,7 +77,7 @@ ISR(TWI_vect) { | ||||
|     case TW_ST_SLA_ACK: | ||||
|     case TW_ST_DATA_ACK: | ||||
|         // master is requesting data, call the send callback | ||||
|         if(i2c_slave_recv_cb != NULL) { | ||||
|         if (i2c_slave_recv_cb != NULL) { | ||||
|             TWDR = i2c_slave_send_cb(); | ||||
|         } | ||||
|         TWCR = BIT(TWIE) | BIT(TWINT) | BIT(TWEA) | BIT(TWEN); | ||||
|   | ||||
| @@ -10,9 +10,9 @@ | ||||
| #include <stdint.h> | ||||
|  | ||||
| struct Gpio { | ||||
|     volatile uint8_t * pin; | ||||
|     volatile uint8_t * ddr; | ||||
|     volatile uint8_t * port; | ||||
|     volatile uint8_t *pin; | ||||
|     volatile uint8_t *ddr; | ||||
|     volatile uint8_t *port; | ||||
|     uint8_t value; | ||||
| }; | ||||
|  | ||||
| @@ -25,9 +25,9 @@ struct Gpio { | ||||
| } | ||||
| // clang-format on | ||||
|  | ||||
| bool gpio_get(struct Gpio * gpio); | ||||
| void gpio_set(struct Gpio * gpio, bool value); | ||||
| bool gpio_get_dir(struct Gpio * gpio); | ||||
| void gpio_set_dir(struct Gpio * gpio, bool value); | ||||
| bool gpio_get(struct Gpio *gpio); | ||||
| void gpio_set(struct Gpio *gpio, bool value); | ||||
| bool gpio_get_dir(struct Gpio *gpio); | ||||
| void gpio_set_dir(struct Gpio *gpio, bool value); | ||||
|  | ||||
| #endif // _ARCH_GPIO_H | ||||
|   | ||||
| @@ -3,7 +3,12 @@ | ||||
| #ifndef _ARCH_I2C_SLAVE_H | ||||
| #define _ARCH_I2C_SLAVE_H | ||||
|  | ||||
| void i2c_slave_init(uint8_t address, void (*new_cb)(), void (*recv_cb)(uint8_t), uint8_t (*send_cb)()); | ||||
| void i2c_slave_init( | ||||
|     uint8_t address, | ||||
|     void (*new_cb)(), | ||||
|     void (*recv_cb)(uint8_t), | ||||
|     uint8_t (*send_cb)() | ||||
| ); | ||||
| void i2c_slave_stop(); | ||||
|  | ||||
| #endif // _ARCH_I2C_SLAVE_H | ||||
|   | ||||
| @@ -6,12 +6,12 @@ | ||||
| #include <stdint.h> | ||||
|  | ||||
| struct Uart { | ||||
|     volatile uint8_t * a; | ||||
|     volatile uint8_t * b; | ||||
|     volatile uint8_t * c; | ||||
|     volatile uint8_t * data; | ||||
|     volatile uint8_t * baud_l; | ||||
|     volatile uint8_t * baud_h; | ||||
|     volatile uint8_t *a; | ||||
|     volatile uint8_t *b; | ||||
|     volatile uint8_t *c; | ||||
|     volatile uint8_t *data; | ||||
|     volatile uint8_t *baud_l; | ||||
|     volatile uint8_t *baud_h; | ||||
|     uint8_t a_read; | ||||
|     uint8_t a_write; | ||||
|     uint8_t a_init; | ||||
| @@ -19,18 +19,18 @@ struct Uart { | ||||
|     uint8_t c_init; | ||||
| }; | ||||
|  | ||||
| void uart_init(struct Uart * uart, uint32_t baud); | ||||
| void uart_init(struct Uart *uart, uint32_t baud); | ||||
|  | ||||
| int16_t uart_count(); | ||||
| struct Uart * uart_new(int16_t num); | ||||
| struct Uart *uart_new(int16_t num); | ||||
|  | ||||
| uint8_t uart_can_read(struct Uart * uart); | ||||
| uint8_t uart_can_write(struct Uart * uart); | ||||
| uint8_t uart_can_read(struct Uart *uart); | ||||
| uint8_t uart_can_write(struct Uart *uart); | ||||
|  | ||||
| uint8_t uart_read(struct Uart * uart); | ||||
| void uart_write(struct Uart * uart, uint8_t data); | ||||
| uint8_t uart_read(struct Uart *uart); | ||||
| void uart_write(struct Uart *uart, uint8_t data); | ||||
|  | ||||
| extern struct Uart * uart_stdio; | ||||
| extern struct Uart *uart_stdio; | ||||
| void uart_stdio_init(int16_t num, uint32_t baud); | ||||
|  | ||||
| #endif // _ARCH_UART_H | ||||
|   | ||||
| @@ -43,10 +43,10 @@ | ||||
| // clang-format on | ||||
|  | ||||
| int16_t uart_count() { | ||||
|     return sizeof(UARTS)/sizeof(struct Uart); | ||||
|     return sizeof(UARTS) / sizeof(struct Uart); | ||||
| } | ||||
|  | ||||
| struct Uart * uart_new(int16_t num) { | ||||
| struct Uart *uart_new(int16_t num) { | ||||
|     if (num < uart_count()) { | ||||
|         return &UARTS[num]; | ||||
|     } else { | ||||
| @@ -54,40 +54,40 @@ struct Uart * uart_new(int16_t num) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| void uart_init(struct Uart * uart, uint32_t baud) { | ||||
| void uart_init(struct Uart *uart, uint32_t baud) { | ||||
|     uint32_t baud_prescale = (F_CPU / (baud * 16UL)) - 1; | ||||
|     *(uart->baud_h) = (uint8_t)(baud_prescale>>8); | ||||
|     *(uart->baud_h) = (uint8_t)(baud_prescale >> 8); | ||||
|     *(uart->baud_l) = (uint8_t)(baud_prescale); | ||||
|     *(uart->a) = uart->a_init; | ||||
|     *(uart->b) = uart->b_init; | ||||
|     *(uart->c) = uart->c_init; | ||||
| } | ||||
|  | ||||
| uint8_t uart_can_read(struct Uart * uart) { | ||||
| uint8_t uart_can_read(struct Uart *uart) { | ||||
|     return (*(uart->a)) & uart->a_read; | ||||
| } | ||||
|  | ||||
| uint8_t uart_read(struct Uart * uart) { | ||||
|     while (!uart_can_read(uart)) ; | ||||
| uint8_t uart_read(struct Uart *uart) { | ||||
|     while (!uart_can_read(uart)) {} | ||||
|     return *(uart->data); | ||||
| } | ||||
|  | ||||
| uint8_t uart_can_write(struct Uart * uart) { | ||||
| uint8_t uart_can_write(struct Uart *uart) { | ||||
|     return (*(uart->a)) & uart->a_write; | ||||
| } | ||||
|  | ||||
| void uart_write(struct Uart * uart, uint8_t data) { | ||||
|     while (!uart_can_write(uart)) ; | ||||
| void uart_write(struct Uart *uart, uint8_t data) { | ||||
|     while (!uart_can_write(uart)) {} | ||||
|     *(uart->data) = data; | ||||
| } | ||||
|  | ||||
| struct Uart * uart_stdio = NULL; | ||||
| struct Uart *uart_stdio = NULL; | ||||
|  | ||||
| int16_t uart_stdio_get(FILE * stream) { | ||||
| int16_t uart_stdio_get(FILE *stream) { | ||||
|     return (int16_t)uart_read(uart_stdio); | ||||
| } | ||||
|  | ||||
| int16_t uart_stdio_put(char data, FILE * stream) { | ||||
| int16_t uart_stdio_put(char data, FILE *stream) { | ||||
|     uart_write(uart_stdio, (uint8_t)data); | ||||
|     return 0; | ||||
| } | ||||
| @@ -95,8 +95,8 @@ int16_t uart_stdio_put(char data, FILE * stream) { | ||||
| FILE uart_stdio_file = FDEV_SETUP_STREAM(uart_stdio_put, uart_stdio_get, _FDEV_SETUP_RW); | ||||
|  | ||||
| void uart_stdio_init(int16_t num, uint32_t baud) { | ||||
|     struct Uart * uart = uart_new(num); | ||||
|     if(uart != NULL) { | ||||
|     struct Uart *uart = uart_new(num); | ||||
|     if (uart != NULL) { | ||||
|         uart_init(uart, baud); | ||||
|         uart_stdio = uart; | ||||
|         stdin = stdout = stderr = &uart_stdio_file; | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| #include <common/i2c.h> | ||||
|  | ||||
| int16_t smbus_read(uint8_t address, uint8_t command, uint16_t * data) { | ||||
| int16_t smbus_read(uint8_t address, uint8_t command, uint16_t *data) { | ||||
|     return i2c_get(NULL, address, command, (uint8_t *)data, 2); | ||||
| } | ||||
|  | ||||
| @@ -16,7 +16,8 @@ void battery_debug(void) { | ||||
|     uint16_t data = 0; | ||||
|     int16_t res = 0; | ||||
|  | ||||
|     #define command(N, A, V) { \ | ||||
| #define command(N, A, V) \ | ||||
|     { \ | ||||
|         printf(#N ": "); \ | ||||
|         res = smbus_read(A, V, &data); \ | ||||
|         if (res < 0) { \ | ||||
| @@ -45,5 +46,5 @@ void battery_debug(void) { | ||||
|     command(ProchotOption1, 0x09, 0x3D); | ||||
|     command(ProchotStatus, 0x09, 0x3A); | ||||
|  | ||||
|     #undef command | ||||
| #undef command | ||||
| } | ||||
|   | ||||
| @@ -7,6 +7,6 @@ | ||||
|  | ||||
| void i2c_init(uint32_t baud) { | ||||
|     TWAR = 0; | ||||
|     TWBR = (uint8_t)(((F_CPU / baud) - 16 ) / 2); | ||||
|     TWBR = (uint8_t)(((F_CPU / baud) - 16) / 2); | ||||
|     TWCR = 0; | ||||
| } | ||||
|   | ||||
| @@ -89,7 +89,6 @@ static struct Gpio GPIOS[24] = { | ||||
|     GPIO(A, 0), GPIO(A, 1), | ||||
| }; | ||||
| #endif // !defined(FLIP) | ||||
| // clang-format on | ||||
|  | ||||
| enum ParallelState { | ||||
|     PARALLEL_STATE_UNKNOWN, | ||||
| @@ -101,47 +100,51 @@ enum ParallelState { | ||||
| // Parallel struct definition | ||||
| // See http://efplus.com/techref/io/parallel/1284/eppmode.htm | ||||
| struct Parallel { | ||||
|     #define PIN(N, P) struct Gpio * N; | ||||
| #define PIN(N, P) struct Gpio *N; | ||||
|     PINS | ||||
|     #undef PIN | ||||
| #undef PIN | ||||
|     enum ParallelState state; | ||||
| }; | ||||
|  | ||||
| // Parallel struct instance | ||||
| static struct Parallel PORT = { | ||||
|     #define PIN(N, P) .N = &GPIOS[P - 1], | ||||
| #define PIN(N, P) .N = &GPIOS[P - 1], | ||||
|     PINS | ||||
|     #undef PIN | ||||
| #undef PIN | ||||
|     .state = PARALLEL_STATE_UNKNOWN, | ||||
| }; | ||||
|  | ||||
| // clang-format on | ||||
|  | ||||
| // Set port to all high-impedance inputs | ||||
| void parallel_hiz(struct Parallel * port) { | ||||
|     #define PIN(N, P) \ | ||||
|         gpio_set_dir(port->N, false); \ | ||||
|         gpio_set(port->N, false); | ||||
| void parallel_hiz(struct Parallel *port) { | ||||
| #define PIN(N, P) \ | ||||
|     gpio_set_dir(port->N, false); \ | ||||
|     gpio_set(port->N, false); | ||||
|     PINS | ||||
|     #undef PIN | ||||
| #undef PIN | ||||
| } | ||||
|  | ||||
| // Place all data lines in high or low impendance state | ||||
| void parallel_data_dir(struct Parallel * port, bool dir) { | ||||
|     #define DATA_BIT(B) gpio_set_dir(port->d ## B, dir); | ||||
| void parallel_data_dir(struct Parallel *port, bool dir) { | ||||
| #define DATA_BIT(B) gpio_set_dir(port->d##B, dir); | ||||
|     DATA_BITS | ||||
|     #undef DATA_BIT | ||||
| #undef DATA_BIT | ||||
| } | ||||
| #define parallel_data_forward(P) parallel_data_dir(P, true) | ||||
| #define parallel_data_reverse(P) parallel_data_dir(P, false) | ||||
|  | ||||
| void parallel_data_set_high(struct Parallel * port, uint8_t byte) { | ||||
| void parallel_data_set_high(struct Parallel *port, uint8_t byte) { | ||||
|     // By convention all lines are high, so only set the ones needed | ||||
|     #define DATA_BIT(B) if (!(byte & (1 << B))) gpio_set(port->d ## B, true); | ||||
| #define DATA_BIT(B) \ | ||||
|     if (!(byte & (1 << B))) \ | ||||
|         gpio_set(port->d##B, true); | ||||
|     DATA_BITS | ||||
|     #undef DATA_BIT | ||||
| #undef DATA_BIT | ||||
| } | ||||
|  | ||||
| // Set port to initial state required before being able to perform cycles | ||||
| void parallel_reset(struct Parallel * port, bool host) { | ||||
| void parallel_reset(struct Parallel *port, bool host) { | ||||
|     parallel_hiz(port); | ||||
|  | ||||
|     // nRESET: output on host, input on peripherals | ||||
| @@ -166,9 +169,9 @@ void parallel_reset(struct Parallel * port, bool host) { | ||||
|     gpio_set_dir(port->wait_n, !host); | ||||
|  | ||||
|     // Pull up data lines on host, leave floating on peripherals | ||||
|     #define DATA_BIT(B) gpio_set(port->d ## B, host); | ||||
| #define DATA_BIT(B) gpio_set(port->d##B, host); | ||||
|     DATA_BITS | ||||
|     #undef DATA_BIT | ||||
| #undef DATA_BIT | ||||
|  | ||||
|     //TODO: something with straps | ||||
|  | ||||
| @@ -180,42 +183,53 @@ void parallel_reset(struct Parallel * port, bool host) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| void parallel_state(struct Parallel * port, enum ParallelState state) { | ||||
| void parallel_state(struct Parallel *port, enum ParallelState state) { | ||||
|     if (port->state != state) { | ||||
|         switch (state) { | ||||
|             case PARALLEL_STATE_UNKNOWN: | ||||
|                 return; | ||||
|             case PARALLEL_STATE_HIZ: | ||||
|                 parallel_hiz(port); | ||||
|                 break; | ||||
|             case PARALLEL_STATE_HOST: | ||||
|                 parallel_reset(port, true); | ||||
|                 break; | ||||
|             case PARALLEL_STATE_PERIPHERAL: | ||||
|                 parallel_reset(port, false); | ||||
|                 break; | ||||
|         case PARALLEL_STATE_UNKNOWN: | ||||
|             return; | ||||
|         case PARALLEL_STATE_HIZ: | ||||
|             parallel_hiz(port); | ||||
|             break; | ||||
|         case PARALLEL_STATE_HOST: | ||||
|             parallel_reset(port, true); | ||||
|             break; | ||||
|         case PARALLEL_STATE_PERIPHERAL: | ||||
|             parallel_reset(port, false); | ||||
|             break; | ||||
|         } | ||||
|         port->state = state; | ||||
|     } | ||||
| } | ||||
|  | ||||
| uint8_t parallel_read_data(struct Parallel * port) { | ||||
| uint8_t parallel_read_data(struct Parallel *port) { | ||||
|     uint8_t byte = 0; | ||||
|     #define DATA_BIT(B) if (gpio_get(port->d ## B)) byte |= (1 << B); | ||||
| #define DATA_BIT(B) \ | ||||
|     if (gpio_get(port->d##B)) \ | ||||
|         byte |= (1 << B); | ||||
|     DATA_BITS | ||||
|     #undef DATA_BIT | ||||
| #undef DATA_BIT | ||||
|     return byte; | ||||
| } | ||||
|  | ||||
| void parallel_write_data(struct Parallel * port, uint8_t byte) { | ||||
| void parallel_write_data(struct Parallel *port, uint8_t byte) { | ||||
|     // By convention all lines are high, so only set the ones needed | ||||
|     #define DATA_BIT(B) if (!(byte & (1 << B))) gpio_set(port->d ## B, false); | ||||
|  | ||||
| #define DATA_BIT(B) \ | ||||
|     if (!(byte & (1 << B))) \ | ||||
|         gpio_set(port->d##B, false); | ||||
|     DATA_BITS | ||||
|     #undef DATA_BIT | ||||
| #undef DATA_BIT | ||||
| } | ||||
|  | ||||
| //TODO: timeout | ||||
| int16_t parallel_transaction(struct Parallel * port, uint8_t * data, int16_t length, bool read, bool addr) { | ||||
| int16_t parallel_transaction( | ||||
|     struct Parallel *port, | ||||
|     uint8_t *data, | ||||
|     int16_t length, | ||||
|     bool read, | ||||
|     bool addr | ||||
| ) { | ||||
|     if (!read) { | ||||
|         // Set write line low | ||||
|         gpio_set(port->write_n, false); | ||||
| @@ -285,7 +299,7 @@ int16_t parallel_transaction(struct Parallel * port, uint8_t * data, int16_t len | ||||
|  | ||||
| // host write -> peripheral read | ||||
| // host read -> peripheral write | ||||
| bool parallel_peripheral_cycle(struct Parallel * port, uint8_t * data, bool * read, bool * addr) { | ||||
| bool parallel_peripheral_cycle(struct Parallel *port, uint8_t *data, bool *read, bool *addr) { | ||||
|     if (!gpio_get(port->reset_n)) { | ||||
|         // XXX: Give host some time to get ready | ||||
|         _delay_ms(1); | ||||
| @@ -337,23 +351,28 @@ static uint8_t ZERO = 0x00; | ||||
| static uint8_t SPI_ENABLE = 0xFE; | ||||
| static uint8_t SPI_DATA = 0xFD; | ||||
|  | ||||
| int16_t parallel_ecms_read(struct Parallel *port, uint16_t addr, uint8_t * data, int16_t length) { | ||||
| int16_t parallel_ecms_read(struct Parallel *port, uint16_t addr, uint8_t *data, int16_t length) { | ||||
|     int16_t res; | ||||
|  | ||||
|     res = parallel_set_address(port, &ADDRESS_ECMSADDR1, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     res = parallel_write(port, ((uint8_t *)&addr) + 1, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     res = parallel_set_address(port, &ADDRESS_ECMSADDR0, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     res = parallel_write(port, (uint8_t *)&addr, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     res = parallel_set_address(port, &ADDRESS_ECMSDATA, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     return parallel_read(port, data, length); | ||||
| } | ||||
| @@ -363,29 +382,35 @@ int16_t parallel_spi_reset(struct Parallel *port) { | ||||
|     int16_t res; | ||||
|  | ||||
|     res = parallel_set_address(port, &ADDRESS_INDAR1, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     res = parallel_write(port, &SPI_ENABLE, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     res = parallel_set_address(port, &ADDRESS_INDDR, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     return parallel_write(port, &ZERO, 1); | ||||
| } | ||||
|  | ||||
| // Enable chip and read or write data | ||||
| int16_t parallel_spi_transaction(struct Parallel *port, uint8_t * data, int16_t length, bool read) { | ||||
| int16_t parallel_spi_transaction(struct Parallel *port, uint8_t *data, int16_t length, bool read) { | ||||
|     int16_t res; | ||||
|  | ||||
|     res = parallel_set_address(port, &ADDRESS_INDAR1, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     res = parallel_write(port, &SPI_DATA, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     res = parallel_set_address(port, &ADDRESS_INDDR, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     return parallel_transaction(port, data, length, read, false); | ||||
| } | ||||
| @@ -394,16 +419,22 @@ int16_t parallel_spi_transaction(struct Parallel *port, uint8_t * data, int16_t | ||||
| #define parallel_spi_write(P, D, L) parallel_spi_transaction(P, D, L, false) | ||||
|  | ||||
| // "Hardware" accelerated SPI programming, requires ECINDARs to be set | ||||
| int16_t parallel_spi_program(struct Parallel * port, uint8_t * data, int16_t length, bool initialized) { | ||||
| int16_t parallel_spi_program( | ||||
|     struct Parallel *port, | ||||
|     uint8_t *data, | ||||
|     int16_t length, | ||||
|     bool initialized | ||||
| ) { | ||||
|     static uint8_t aai[6] = { 0xAD, 0, 0, 0, 0, 0 }; | ||||
|     int16_t res; | ||||
|     int16_t i; | ||||
|     uint8_t status; | ||||
|  | ||||
|     for(i = 0; (i + 1) < length; i+=2) { | ||||
|     for (i = 0; (i + 1) < length; i += 2) { | ||||
|         // Disable chip to begin command | ||||
|         res = parallel_spi_reset(port); | ||||
|         if (res < 0) return res; | ||||
|         if (res < 0) | ||||
|             return res; | ||||
|  | ||||
|         if (!initialized) { | ||||
|             // If not initialized, the start address must be sent | ||||
| @@ -415,7 +446,8 @@ int16_t parallel_spi_program(struct Parallel * port, uint8_t * data, int16_t len | ||||
|             aai[5] = data[i + 1]; | ||||
|  | ||||
|             res = parallel_spi_write(port, aai, 6); | ||||
|             if (res < 0) return res; | ||||
|             if (res < 0) | ||||
|                 return res; | ||||
|  | ||||
|             initialized = true; | ||||
|         } else { | ||||
| @@ -423,30 +455,35 @@ int16_t parallel_spi_program(struct Parallel * port, uint8_t * data, int16_t len | ||||
|             aai[2] = data[i + 1]; | ||||
|  | ||||
|             res = parallel_spi_write(port, aai, 3); | ||||
|             if (res < 0) return res; | ||||
|             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; | ||||
|             if (res < 0) | ||||
|                 return res; | ||||
|  | ||||
|             status = 0x05; | ||||
|             res = parallel_spi_write(port, &status, 1); | ||||
|             if (res < 0) return res; | ||||
|             if (res < 0) | ||||
|                 return res; | ||||
|  | ||||
|             res = parallel_spi_read(port, &status, 1); | ||||
|             if (res < 0) return res; | ||||
|             if (res < 0) | ||||
|                 return res; | ||||
|  | ||||
|             if (!(status & 1)) break; | ||||
|             if (!(status & 1)) | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return i; | ||||
| } | ||||
|  | ||||
| int16_t serial_transaction(uint8_t * data, int16_t length, bool read) { | ||||
| int16_t serial_transaction(uint8_t *data, int16_t length, bool read) { | ||||
|     int16_t i; | ||||
|     for (i = 0; i < length; i++) { | ||||
|         if (read) { | ||||
| @@ -465,7 +502,7 @@ int16_t serial_transaction(uint8_t * data, int16_t length, bool read) { | ||||
| int parallel_main(void) { | ||||
|     int16_t res = 0; | ||||
|  | ||||
|     struct Parallel * port = &PORT; | ||||
|     struct Parallel *port = &PORT; | ||||
|     parallel_state(port, PARALLEL_STATE_HIZ); | ||||
|  | ||||
|     static uint8_t data[128]; | ||||
| @@ -481,7 +518,8 @@ int parallel_main(void) { | ||||
|     for (;;) { | ||||
|         // Read command and length | ||||
|         res = serial_read(data, 2); | ||||
|         if (res < 0) goto err; | ||||
|         if (res < 0) | ||||
|             goto err; | ||||
|         // Command is a character | ||||
|         command = (char)data[0]; | ||||
|  | ||||
| @@ -499,164 +537,183 @@ int parallel_main(void) { | ||||
|         // Length is received data + 1 | ||||
|         length = ((int16_t)data[1]) + 1; | ||||
|         // Truncate length to size of data | ||||
|         if (length > sizeof(data)) length = sizeof(data); | ||||
|         if (length > sizeof(data)) | ||||
|             length = sizeof(data); | ||||
|  | ||||
|         switch (command) { | ||||
|             // Buffer size | ||||
|             case 'B': | ||||
|                 // Fill buffer size - 1 | ||||
|                 for (i = 0; i < length; i++) { | ||||
|                     if (i == 0) { | ||||
|                         data[i] = (uint8_t)(sizeof(data) - 1); | ||||
|                     } else { | ||||
|                         data[i] = 0; | ||||
|         // Buffer size | ||||
|         case 'B': | ||||
|             // Fill buffer size - 1 | ||||
|             for (i = 0; i < length; i++) { | ||||
|                 if (i == 0) { | ||||
|                     data[i] = (uint8_t)(sizeof(data) - 1); | ||||
|                 } else { | ||||
|                     data[i] = 0; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Write data to serial | ||||
|             res = serial_write(data, length); | ||||
|             if (res < 0) | ||||
|                 goto err; | ||||
|  | ||||
|             break; | ||||
|  | ||||
|         // Debug console | ||||
|         case 'C': | ||||
|             // Set parallel lines to peripheral mode | ||||
|             parallel_state(port, PARALLEL_STATE_PERIPHERAL); | ||||
|  | ||||
|             // Tell the user the console is ready | ||||
|             serial_write(console_msg, sizeof(console_msg)); | ||||
|             for (;;) { | ||||
|                 bool read = false; | ||||
|                 bool addr = false; | ||||
|                 if (parallel_peripheral_cycle(port, data, &read, &addr)) { | ||||
|                     if (!read && !addr) { | ||||
|                         res = serial_write(data, 1); | ||||
|                         if (res < 0) | ||||
|                             goto err; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|                 // Write data to serial | ||||
|                 res = serial_write(data, length); | ||||
|                 if (res < 0) goto err; | ||||
|             break; | ||||
|  | ||||
|                 break; | ||||
|         // Echo | ||||
|         case 'E': | ||||
|             // Read data from serial | ||||
|             res = serial_read(data, length); | ||||
|             if (res < 0) | ||||
|                 goto err; | ||||
|  | ||||
|             // Debug console | ||||
|             case 'C': | ||||
|                 // Set parallel lines to peripheral mode | ||||
|                 parallel_state(port, PARALLEL_STATE_PERIPHERAL); | ||||
|             // Write data to serial | ||||
|             res = serial_write(data, length); | ||||
|             if (res < 0) | ||||
|                 goto err; | ||||
|  | ||||
|                 // Tell the user the console is ready | ||||
|                 serial_write(console_msg, sizeof(console_msg)); | ||||
|                 for (;;) { | ||||
|                     bool read = false; | ||||
|                     bool addr = false; | ||||
|                     if (parallel_peripheral_cycle(port, data, &read, &addr)) { | ||||
|                         if (!read && !addr) { | ||||
|                             res = serial_write(data, 1); | ||||
|                             if (res < 0) goto err; | ||||
|                         } | ||||
|                     } | ||||
|             break; | ||||
|  | ||||
|         // Forced debug console (can be used on all firmware but may miss bytes) | ||||
|         case 'F': | ||||
|             serial_write(console_msg, sizeof(console_msg)); | ||||
|  | ||||
|             // We must be in host mode | ||||
|             parallel_state(port, PARALLEL_STATE_HOST); | ||||
|  | ||||
|             uint16_t head = 0; | ||||
|             for (;;) { | ||||
|                 // Read current position | ||||
|                 res = parallel_ecms_read(port, 0xF00, data, 1); | ||||
|                 if (res < 0) | ||||
|                     goto err; | ||||
|  | ||||
|                 uint16_t tail = (uint16_t)data[0]; | ||||
|                 if (tail == 0 || head == tail) { | ||||
|                     // No new data | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             // Echo | ||||
|             case 'E': | ||||
|                 // Read data from serial | ||||
|                 res = serial_read(data, length); | ||||
|                 if (res < 0) goto err; | ||||
|  | ||||
|                 // Write data to serial | ||||
|                 res = serial_write(data, length); | ||||
|                 if (res < 0) goto err; | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             // Forced debug console (can be used on all firmware but may miss bytes) | ||||
|             case 'F': | ||||
|                 serial_write(console_msg, sizeof(console_msg)); | ||||
|  | ||||
|                 // We must be in host mode | ||||
|                 parallel_state(port, PARALLEL_STATE_HOST); | ||||
|  | ||||
|                 uint16_t head = 0; | ||||
|                 for (;;) { | ||||
|                     // Read current position | ||||
|                     res = parallel_ecms_read(port, 0xF00, data, 1); | ||||
|                     if (res < 0) goto err; | ||||
|  | ||||
|                     uint16_t tail = (uint16_t)data[0]; | ||||
|                     if (tail == 0 || head == tail) { | ||||
|                         // No new data | ||||
|                         continue; | ||||
|                     } | ||||
|  | ||||
|                     if (head == 0) { | ||||
|                         // Set head if necessary | ||||
|                         head = tail; | ||||
|                         continue; | ||||
|                     } | ||||
|  | ||||
|                     while (head != tail) { | ||||
|                         head += 1; | ||||
|                         if (head >= 256) { head = 1; } | ||||
|  | ||||
|                         // Read byte at head | ||||
|                         res = parallel_ecms_read(port, 0xF00 + head, data, 1); | ||||
|                         if (res < 0) goto err; | ||||
|  | ||||
|                         // Print read byte | ||||
|                         serial_write(data, 1); | ||||
|                     } | ||||
|                 if (head == 0) { | ||||
|                     // Set head if necessary | ||||
|                     head = tail; | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 break; | ||||
|                 while (head != tail) { | ||||
|                     head += 1; | ||||
|                     if (head >= 256) { | ||||
|                         head = 1; | ||||
|                     } | ||||
|  | ||||
|             // Read data | ||||
|             case 'R': | ||||
|                 parallel_state(port, PARALLEL_STATE_HOST); | ||||
|                     // Read byte at head | ||||
|                     res = parallel_ecms_read(port, 0xF00 + head, data, 1); | ||||
|                     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; | ||||
|                     // Print read byte | ||||
|                     serial_write(data, 1); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|                 // Read data from parallel | ||||
|                 res = parallel_read(port, data, length); | ||||
|                 if (res < 0) goto err; | ||||
|             break; | ||||
|  | ||||
|                 // Write data to serial | ||||
|                 res = serial_write(data, length); | ||||
|                 if (res < 0) goto err; | ||||
|         // Read data | ||||
|         case 'R': | ||||
|             parallel_state(port, PARALLEL_STATE_HOST); | ||||
|  | ||||
|                 break; | ||||
|             // Update parallel address if necessary | ||||
|             if (set_address) { | ||||
|                 res = parallel_set_address(port, &address, 1); | ||||
|                 if (res < 0) | ||||
|                     goto err; | ||||
|                 set_address = false; | ||||
|             } | ||||
|  | ||||
|             // Accelerated program function | ||||
|             case 'P': | ||||
|                 parallel_state(port, PARALLEL_STATE_HOST); | ||||
|             // Read data from parallel | ||||
|             res = parallel_read(port, data, length); | ||||
|             if (res < 0) | ||||
|                 goto err; | ||||
|  | ||||
|                 // Read data from serial | ||||
|                 res = serial_read(data, length); | ||||
|                 if (res < 0) goto err; | ||||
|             // Write data to serial | ||||
|             res = serial_write(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; | ||||
|             break; | ||||
|  | ||||
|                 // Send ACK of data length | ||||
|                 data[0] = (uint8_t)(length - 1); | ||||
|                 res = serial_write(data, 1); | ||||
|                 if (res < 0) goto err; | ||||
|         // Accelerated program function | ||||
|         case 'P': | ||||
|             parallel_state(port, PARALLEL_STATE_HOST); | ||||
|  | ||||
|                 break; | ||||
|             // Read data from serial | ||||
|             res = serial_read(data, length); | ||||
|             if (res < 0) | ||||
|                 goto err; | ||||
|  | ||||
|             // Write data | ||||
|             case 'W': | ||||
|                 parallel_state(port, PARALLEL_STATE_HOST); | ||||
|             // Run accelerated programming function | ||||
|             res = parallel_spi_program(port, data, length, program_aai); | ||||
|             if (res < 0) | ||||
|                 goto err; | ||||
|             program_aai = true; | ||||
|  | ||||
|                 // Read data from serial | ||||
|                 res = serial_read(data, length); | ||||
|                 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; | ||||
|  | ||||
|                 // Update parallel address if necessary | ||||
|                 if (set_address) { | ||||
|                     res = parallel_set_address(port, &address, 1); | ||||
|                     if (res < 0) goto err; | ||||
|                     set_address = false; | ||||
|                 } | ||||
|             break; | ||||
|  | ||||
|                 // Write data to parallel | ||||
|                 res = parallel_write(port, data, length); | ||||
|                 if (res < 0) goto err; | ||||
|         // Write data | ||||
|         case 'W': | ||||
|             parallel_state(port, PARALLEL_STATE_HOST); | ||||
|  | ||||
|                 // Send ACK of data length | ||||
|                 data[0] = (uint8_t)(length - 1); | ||||
|                 res = serial_write(data, 1); | ||||
|                 if (res < 0) goto err; | ||||
|             // Read data from serial | ||||
|             res = serial_read(data, length); | ||||
|             if (res < 0) | ||||
|                 goto err; | ||||
|  | ||||
|                 break; | ||||
|             // 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 | ||||
|             res = parallel_write(port, data, length); | ||||
|             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; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| #include <common/i2c.h> | ||||
|  | ||||
| int16_t smbus_read(uint8_t address, uint8_t command, uint16_t * data) { | ||||
| int16_t smbus_read(uint8_t address, uint8_t command, uint16_t *data) { | ||||
|     return i2c_get(NULL, address, command, (uint8_t *)data, 2); | ||||
| } | ||||
|  | ||||
| @@ -16,7 +16,8 @@ void battery_debug(void) { | ||||
|     uint16_t data = 0; | ||||
|     int16_t res = 0; | ||||
|  | ||||
|     #define command(N, A, V) { \ | ||||
| #define command(N, A, V) \ | ||||
|     { \ | ||||
|         printf(#N ": "); \ | ||||
|         res = smbus_read(A, V, &data); \ | ||||
|         if (res < 0) { \ | ||||
| @@ -45,5 +46,5 @@ void battery_debug(void) { | ||||
|     command(ProchotOption1, 0x09, 0x3D); | ||||
|     command(ProchotStatus, 0x09, 0x3A); | ||||
|  | ||||
|     #undef command | ||||
| #undef command | ||||
| } | ||||
|   | ||||
| @@ -7,6 +7,6 @@ | ||||
|  | ||||
| void i2c_init(uint32_t baud) { | ||||
|     TWAR = 0; | ||||
|     TWBR = (uint8_t)(((F_CPU / baud) - 16 ) / 2); | ||||
|     TWBR = (uint8_t)(((F_CPU / baud) - 16) / 2); | ||||
|     TWCR = 0; | ||||
| } | ||||
|   | ||||
| @@ -12,6 +12,7 @@ | ||||
| #include <arch/uart.h> | ||||
|  | ||||
| // clang-format off | ||||
|  | ||||
| // Mapping of 24-pin ribbon cable to parallel pins. See schematic | ||||
| #define PINS \ | ||||
|     /* Data (KSO0 - KSO7) - bi-directional */ \ | ||||
| @@ -65,50 +66,53 @@ static struct Gpio GPIOS[13] = { | ||||
|     GPIO(C, 1), | ||||
|     GPIO(C, 0), | ||||
| }; | ||||
|  | ||||
| // clang-format on | ||||
|  | ||||
| // Parallel struct definition | ||||
| // See http://efplus.com/techref/io/parallel/1284/eppmode.htm | ||||
| struct Parallel { | ||||
|     #define PIN(N, P) struct Gpio * N; | ||||
| #define PIN(N, P) struct Gpio *N; | ||||
|     PINS | ||||
|     #undef PIN | ||||
| #undef PIN | ||||
| }; | ||||
|  | ||||
| // Parallel struct instance | ||||
| static struct Parallel PORT = { | ||||
|     #define PIN(N, P) .N = &GPIOS[P - 1], | ||||
| #define PIN(N, P) .N = &GPIOS[P - 1], | ||||
|     PINS | ||||
|     #undef PIN | ||||
| #undef PIN | ||||
| }; | ||||
|  | ||||
| // Set port to all high-impedance inputs | ||||
| void parallel_hiz(struct Parallel * port) { | ||||
|     #define PIN(N, P) \ | ||||
|         gpio_set_dir(port->N, false); \ | ||||
|         gpio_set(port->N, false); | ||||
| void parallel_hiz(struct Parallel *port) { | ||||
| #define PIN(N, P) \ | ||||
|     gpio_set_dir(port->N, false); \ | ||||
|     gpio_set(port->N, false); | ||||
|     PINS | ||||
|     #undef PIN | ||||
| #undef PIN | ||||
| } | ||||
|  | ||||
| // Place all data lines in high or low impendance state | ||||
| void parallel_data_dir(struct Parallel * port, bool dir) { | ||||
|     #define DATA_BIT(B) gpio_set_dir(port->d ## B, dir); | ||||
| void parallel_data_dir(struct Parallel *port, bool dir) { | ||||
| #define DATA_BIT(B) gpio_set_dir(port->d##B, dir); | ||||
|     DATA_BITS | ||||
|     #undef DATA_BIT | ||||
| #undef DATA_BIT | ||||
| } | ||||
| #define parallel_data_forward(P) parallel_data_dir(P, true) | ||||
| #define parallel_data_reverse(P) parallel_data_dir(P, false) | ||||
|  | ||||
| void parallel_data_set_high(struct Parallel * port, uint8_t byte) { | ||||
| void parallel_data_set_high(struct Parallel *port, uint8_t byte) { | ||||
|     // By convention all lines are high, so only set the ones needed | ||||
|     #define DATA_BIT(B) if (!(byte & (1 << B))) gpio_set(port->d ## B, true); | ||||
| #define DATA_BIT(B) \ | ||||
|     if (!(byte & (1 << B))) \ | ||||
|         gpio_set(port->d##B, true); | ||||
|     DATA_BITS | ||||
|     #undef DATA_BIT | ||||
| #undef DATA_BIT | ||||
| } | ||||
|  | ||||
| // Set port to initial state required before being able to perform cycles | ||||
| void parallel_reset(struct Parallel * port, bool host) { | ||||
| void parallel_reset(struct Parallel *port, bool host) { | ||||
|     parallel_hiz(port); | ||||
|  | ||||
|     // nRESET: output on host, input on peripherals | ||||
| @@ -133,9 +137,9 @@ void parallel_reset(struct Parallel * port, bool host) { | ||||
|     gpio_set_dir(port->wait_n, !host); | ||||
|  | ||||
|     // Pull up data lines on host, leave floating on peripherals | ||||
|     #define DATA_BIT(B) gpio_set(port->d ## B, host); | ||||
| #define DATA_BIT(B) gpio_set(port->d##B, host); | ||||
|     DATA_BITS | ||||
|     #undef DATA_BIT | ||||
| #undef DATA_BIT | ||||
|  | ||||
|     //TODO: something with straps | ||||
|  | ||||
| @@ -147,23 +151,33 @@ void parallel_reset(struct Parallel * port, bool host) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| uint8_t parallel_read_data(struct Parallel * port) { | ||||
| uint8_t parallel_read_data(struct Parallel *port) { | ||||
|     uint8_t byte = 0; | ||||
|     #define DATA_BIT(B) if (gpio_get(port->d ## B)) byte |= (1 << B); | ||||
| #define DATA_BIT(B) \ | ||||
|     if (gpio_get(port->d##B)) \ | ||||
|         byte |= (1 << B); | ||||
|     DATA_BITS | ||||
|     #undef DATA_BIT | ||||
| #undef DATA_BIT | ||||
|     return byte; | ||||
| } | ||||
|  | ||||
| void parallel_write_data(struct Parallel * port, uint8_t byte) { | ||||
| void parallel_write_data(struct Parallel *port, uint8_t byte) { | ||||
|     // By convention all lines are high, so only set the ones needed | ||||
|     #define DATA_BIT(B) if (!(byte & (1 << B))) gpio_set(port->d ## B, false); | ||||
| #define DATA_BIT(B) \ | ||||
|     if (!(byte & (1 << B))) \ | ||||
|         gpio_set(port->d##B, false); | ||||
|     DATA_BITS | ||||
|     #undef DATA_BIT | ||||
| #undef DATA_BIT | ||||
| } | ||||
|  | ||||
| //TODO: timeout | ||||
| int16_t parallel_transaction(struct Parallel * port, uint8_t * data, int16_t length, bool read, bool addr) { | ||||
| int16_t parallel_transaction( | ||||
|     struct Parallel *port, | ||||
|     uint8_t *data, | ||||
|     int16_t length, | ||||
|     bool read, | ||||
|     bool addr | ||||
| ) { | ||||
|     if (!read) { | ||||
|         // Set write line low | ||||
|         gpio_set(port->write_n, false); | ||||
| @@ -234,7 +248,7 @@ int16_t parallel_transaction(struct Parallel * port, uint8_t * data, int16_t len | ||||
|  | ||||
| // host write -> peripheral read | ||||
| // host read -> peripheral write | ||||
| bool parallel_peripheral_cycle(struct Parallel * port, uint8_t * data, bool * read, bool * addr) { | ||||
| bool parallel_peripheral_cycle(struct Parallel *port, uint8_t *data, bool *read, bool *addr) { | ||||
|     if (!gpio_get(port->reset_n)) { | ||||
|         // XXX: Give host some time to get ready | ||||
|         _delay_ms(1); | ||||
| @@ -283,29 +297,35 @@ int16_t parallel_spi_reset(struct Parallel *port) { | ||||
|     int16_t res; | ||||
|  | ||||
|     res = parallel_set_address(port, &ADDRESS_INDAR1, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     res = parallel_write(port, &SPI_ENABLE, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     res = parallel_set_address(port, &ADDRESS_INDDR, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     return parallel_write(port, &ZERO, 1); | ||||
| } | ||||
|  | ||||
| // Enable chip and read or write data | ||||
| int16_t parallel_spi_transaction(struct Parallel *port, uint8_t * data, int16_t length, bool read) { | ||||
| int16_t parallel_spi_transaction(struct Parallel *port, uint8_t *data, int16_t length, bool read) { | ||||
|     int16_t res; | ||||
|  | ||||
|     res = parallel_set_address(port, &ADDRESS_INDAR1, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     res = parallel_write(port, &SPI_DATA, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     res = parallel_set_address(port, &ADDRESS_INDDR, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     return parallel_transaction(port, data, length, read, false); | ||||
| } | ||||
| @@ -314,16 +334,22 @@ int16_t parallel_spi_transaction(struct Parallel *port, uint8_t * data, int16_t | ||||
| #define parallel_spi_write(P, D, L) parallel_spi_transaction(P, D, L, false) | ||||
|  | ||||
| // "Hardware" accelerated SPI programming, requires ECINDARs to be set | ||||
| int16_t parallel_spi_program(struct Parallel * port, uint8_t * data, int16_t length, bool initialized) { | ||||
| int16_t parallel_spi_program( | ||||
|     struct Parallel *port, | ||||
|     uint8_t *data, | ||||
|     int16_t length, | ||||
|     bool initialized | ||||
| ) { | ||||
|     static uint8_t aai[6] = { 0xAD, 0, 0, 0, 0, 0 }; | ||||
|     int16_t res; | ||||
|     int16_t i; | ||||
|     uint8_t status; | ||||
|  | ||||
|     for(i = 0; (i + 1) < length; i+=2) { | ||||
|     for (i = 0; (i + 1) < length; i += 2) { | ||||
|         // Disable chip to begin command | ||||
|         res = parallel_spi_reset(port); | ||||
|         if (res < 0) return res; | ||||
|         if (res < 0) | ||||
|             return res; | ||||
|  | ||||
|         if (!initialized) { | ||||
|             // If not initialized, the start address must be sent | ||||
| @@ -335,7 +361,8 @@ int16_t parallel_spi_program(struct Parallel * port, uint8_t * data, int16_t len | ||||
|             aai[5] = data[i + 1]; | ||||
|  | ||||
|             res = parallel_spi_write(port, aai, 6); | ||||
|             if (res < 0) return res; | ||||
|             if (res < 0) | ||||
|                 return res; | ||||
|  | ||||
|             initialized = true; | ||||
|         } else { | ||||
| @@ -343,30 +370,35 @@ int16_t parallel_spi_program(struct Parallel * port, uint8_t * data, int16_t len | ||||
|             aai[2] = data[i + 1]; | ||||
|  | ||||
|             res = parallel_spi_write(port, aai, 3); | ||||
|             if (res < 0) return res; | ||||
|             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; | ||||
|             if (res < 0) | ||||
|                 return res; | ||||
|  | ||||
|             status = 0x05; | ||||
|             res = parallel_spi_write(port, &status, 1); | ||||
|             if (res < 0) return res; | ||||
|             if (res < 0) | ||||
|                 return res; | ||||
|  | ||||
|             res = parallel_spi_read(port, &status, 1); | ||||
|             if (res < 0) return res; | ||||
|             if (res < 0) | ||||
|                 return res; | ||||
|  | ||||
|             if (!(status & 1)) break; | ||||
|             if (!(status & 1)) | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return i; | ||||
| } | ||||
|  | ||||
| int16_t serial_transaction(uint8_t * data, int16_t length, bool read) { | ||||
| int16_t serial_transaction(uint8_t *data, int16_t length, bool read) { | ||||
|     int16_t i; | ||||
|     for (i = 0; i < length; i++) { | ||||
|         if (read) { | ||||
| @@ -385,7 +417,7 @@ int16_t serial_transaction(uint8_t * data, int16_t length, bool read) { | ||||
| int16_t parallel_main(void) { | ||||
|     int16_t res = 0; | ||||
|  | ||||
|     struct Parallel * port = &PORT; | ||||
|     struct Parallel *port = &PORT; | ||||
|     parallel_reset(port, true); | ||||
|  | ||||
|     static uint8_t data[128]; | ||||
| @@ -401,7 +433,8 @@ int16_t parallel_main(void) { | ||||
|     for (;;) { | ||||
|         // Read command and length | ||||
|         res = serial_read(data, 2); | ||||
|         if (res < 0) goto err; | ||||
|         if (res < 0) | ||||
|             goto err; | ||||
|         // Command is a character | ||||
|         command = (char)data[0]; | ||||
|  | ||||
| @@ -419,118 +452,133 @@ int16_t parallel_main(void) { | ||||
|         // Length is received data + 1 | ||||
|         length = ((int16_t)data[1]) + 1; | ||||
|         // Truncate length to size of data | ||||
|         if (length > sizeof(data)) length = sizeof(data); | ||||
|         if (length > sizeof(data)) | ||||
|             length = sizeof(data); | ||||
|  | ||||
|         switch (command) { | ||||
|             // Buffer size | ||||
|             case 'B': | ||||
|                 // Fill buffer size - 1 | ||||
|                 for (i = 0; i < length; i++) { | ||||
|                     if (i == 0) { | ||||
|                         data[i] = (uint8_t)(sizeof(data) - 1); | ||||
|                     } else { | ||||
|                         data[i] = 0; | ||||
|                     } | ||||
|         // Buffer size | ||||
|         case 'B': | ||||
|             // Fill buffer size - 1 | ||||
|             for (i = 0; i < length; i++) { | ||||
|                 if (i == 0) { | ||||
|                     data[i] = (uint8_t)(sizeof(data) - 1); | ||||
|                 } else { | ||||
|                     data[i] = 0; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|                 // Write data to serial | ||||
|                 res = serial_write(data, length); | ||||
|                 if (res < 0) goto err; | ||||
|             // Write data to serial | ||||
|             res = serial_write(data, length); | ||||
|             if (res < 0) | ||||
|                 goto err; | ||||
|  | ||||
|                 break; | ||||
|             break; | ||||
|  | ||||
|             // Debug console | ||||
|             case 'C': | ||||
|                 serial_write(console_msg, sizeof(console_msg)); | ||||
|         // Debug console | ||||
|         case 'C': | ||||
|             serial_write(console_msg, sizeof(console_msg)); | ||||
|  | ||||
|                 // Reconfigure as a peripheral | ||||
|                 parallel_reset(port, false); | ||||
|             // Reconfigure as a peripheral | ||||
|             parallel_reset(port, false); | ||||
|  | ||||
|                 for (;;) { | ||||
|                     bool read = false; | ||||
|                     bool addr = false; | ||||
|                     bool ret = parallel_peripheral_cycle(port, data, &read, &addr); | ||||
|             for (;;) { | ||||
|                 bool read = false; | ||||
|                 bool addr = false; | ||||
|                 bool ret = parallel_peripheral_cycle(port, data, &read, &addr); | ||||
|  | ||||
|                     if (ret && !read && !addr) { | ||||
|                         res = serial_write(data, 1); | ||||
|                         if (res < 0) goto err; | ||||
|                     } | ||||
|                 if (ret && !read && !addr) { | ||||
|                     res = serial_write(data, 1); | ||||
|                     if (res < 0) | ||||
|                         goto err; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|                 break; | ||||
|             break; | ||||
|  | ||||
|             // Echo | ||||
|             case 'E': | ||||
|                 // Read data from serial | ||||
|                 res = serial_read(data, length); | ||||
|                 if (res < 0) goto err; | ||||
|         // Echo | ||||
|         case 'E': | ||||
|             // Read data from serial | ||||
|             res = serial_read(data, length); | ||||
|             if (res < 0) | ||||
|                 goto err; | ||||
|  | ||||
|                 // Write data to serial | ||||
|                 res = serial_write(data, length); | ||||
|                 if (res < 0) goto err; | ||||
|             // Write data to serial | ||||
|             res = serial_write(data, length); | ||||
|             if (res < 0) | ||||
|                 goto err; | ||||
|  | ||||
|                 break; | ||||
|             break; | ||||
|  | ||||
|             // Read data | ||||
|             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 | ||||
|         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 | ||||
|                 res = parallel_read(port, data, length); | ||||
|                 if (res < 0) goto err; | ||||
|             // Read data from parallel | ||||
|             res = parallel_read(port, data, length); | ||||
|             if (res < 0) | ||||
|                 goto err; | ||||
|  | ||||
|                 // Write data to serial | ||||
|                 res = serial_write(data, length); | ||||
|                 if (res < 0) goto err; | ||||
|             // Write data to serial | ||||
|             res = serial_write(data, length); | ||||
|             if (res < 0) | ||||
|                 goto err; | ||||
|  | ||||
|                 break; | ||||
|             break; | ||||
|  | ||||
|             // Accelerated program function | ||||
|             case 'P': | ||||
|                 // Read data from serial | ||||
|                 res = serial_read(data, length); | ||||
|                 if (res < 0) goto err; | ||||
|         // 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; | ||||
|             // 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; | ||||
|             // Send ACK of data length | ||||
|             data[0] = (uint8_t)(length - 1); | ||||
|             res = serial_write(data, 1); | ||||
|             if (res < 0) | ||||
|                 goto err; | ||||
|  | ||||
|                 break; | ||||
|             break; | ||||
|  | ||||
|             // Write data | ||||
|             case 'W': | ||||
|                 // Read data from serial | ||||
|                 res = serial_read(data, length); | ||||
|                 if (res < 0) goto err; | ||||
|         // Write data | ||||
|         case 'W': | ||||
|             // Read data from serial | ||||
|             res = serial_read(data, length); | ||||
|             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; | ||||
|                 } | ||||
|             // 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 | ||||
|                 res = parallel_write(port, data, length); | ||||
|                 if (res < 0) goto err; | ||||
|             // Write data to parallel | ||||
|             res = parallel_write(port, data, length); | ||||
|             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; | ||||
|             // Send ACK of data length | ||||
|             data[0] = (uint8_t)(length - 1); | ||||
|             res = serial_write(data, 1); | ||||
|             if (res < 0) | ||||
|                 goto err; | ||||
|  | ||||
|                 break; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -242,13 +242,13 @@ void gpio_init() { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n", | ||||
|             bank, | ||||
| @@ -262,7 +262,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -273,6 +273,6 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #undef bank | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -246,13 +246,13 @@ void gpio_init() { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n", | ||||
|             bank, | ||||
| @@ -266,7 +266,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -277,6 +277,6 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #undef bank | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -240,13 +240,13 @@ void gpio_init() { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n", | ||||
|             bank, | ||||
| @@ -260,7 +260,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -271,6 +271,6 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #undef bank | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -27,31 +27,33 @@ static uint8_t fbuf[4] = { 0, 0, 0, 0 }; | ||||
|  | ||||
| void fcommand(void) { | ||||
|     switch (fcmd) { | ||||
|         // Keyboard backlight | ||||
|         case 0xCA: | ||||
|             switch (fdat) { | ||||
|                 // Set white LED brightness | ||||
|                 case 0x00: | ||||
|                     kbled_set(fbuf[0]); | ||||
|                     break; | ||||
|                 // Get white LED brightness | ||||
|                 case 0x01: | ||||
|                     fbuf[0] = kbled_get(); | ||||
|                     break; | ||||
|                 // Set LED color | ||||
|                 case 0x03: | ||||
|                     kbled_set_color( | ||||
|                         ((uint32_t)fbuf[0]) | | ||||
|                         ((uint32_t)fbuf[1] << 16) | | ||||
|                         ((uint32_t)fbuf[2] << 8) | ||||
|                     ); | ||||
|                     break; | ||||
|                 // Set LED brightness | ||||
|                 case 0x06: | ||||
|                     kbled_set(fbuf[0]); | ||||
|                     break; | ||||
|             } | ||||
|     // Keyboard backlight | ||||
|     case 0xCA: | ||||
|         switch (fdat) { | ||||
|         // Set white LED brightness | ||||
|         case 0x00: | ||||
|             kbled_set(fbuf[0]); | ||||
|             break; | ||||
|         // Get white LED brightness | ||||
|         case 0x01: | ||||
|             fbuf[0] = kbled_get(); | ||||
|             break; | ||||
|         // Set LED color | ||||
|         case 0x03: | ||||
|             // clang-format off | ||||
|             kbled_set_color( | ||||
|                 ((uint32_t)fbuf[0]) | | ||||
|                 ((uint32_t)fbuf[1] << 16) | | ||||
|                 ((uint32_t)fbuf[2] << 8) | ||||
|             ); | ||||
|             // clang-format on | ||||
|             break; | ||||
|         // Set LED brightness | ||||
|         case 0x06: | ||||
|             kbled_set(fbuf[0]); | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -187,48 +189,48 @@ void acpi_write(uint8_t addr, uint8_t data) { | ||||
|     TRACE("acpi_write %02X = %02X\n", addr, data); | ||||
|  | ||||
|     switch (addr) { | ||||
|         // Lid state and other flags | ||||
|         case 0x03: | ||||
|             lid_wake = (bool)(data & BIT(2)); | ||||
|             break; | ||||
|     // Lid state and other flags | ||||
|     case 0x03: | ||||
|         lid_wake = (bool)(data & BIT(2)); | ||||
|         break; | ||||
|  | ||||
|         case 0x68: | ||||
|             acpi_ecos = (enum EcOs)data; | ||||
|             break; | ||||
|     case 0x68: | ||||
|         acpi_ecos = (enum EcOs)data; | ||||
|         break; | ||||
|  | ||||
|         case 0xBC: | ||||
|             battery_set_start_threshold(data); | ||||
|             break; | ||||
|     case 0xBC: | ||||
|         battery_set_start_threshold(data); | ||||
|         break; | ||||
|  | ||||
|         case 0xBD: | ||||
|             battery_set_end_threshold(data); | ||||
|             break; | ||||
|     case 0xBD: | ||||
|         battery_set_end_threshold(data); | ||||
|         break; | ||||
|  | ||||
| #if HAVE_LED_AIRPLANE_N | ||||
|         // Airplane mode LED | ||||
|         case 0xD9: | ||||
|             gpio_set(&LED_AIRPLANE_N, !(bool)(data & BIT(6))); | ||||
|             break; | ||||
|     // Airplane mode LED | ||||
|     case 0xD9: | ||||
|         gpio_set(&LED_AIRPLANE_N, !(bool)(data & BIT(6))); | ||||
|         break; | ||||
| #endif | ||||
|  | ||||
|         case 0xF8: | ||||
|             fcmd = data; | ||||
|             fcommand(); | ||||
|             break; | ||||
|         case 0xF9: | ||||
|             fdat = data; | ||||
|             break; | ||||
|         case 0xFA: | ||||
|             fbuf[0] = data; | ||||
|             break; | ||||
|         case 0xFB: | ||||
|             fbuf[1] = data; | ||||
|             break; | ||||
|         case 0xFC: | ||||
|             fbuf[2] = data; | ||||
|             break; | ||||
|         case 0xFD: | ||||
|             fbuf[3] = data; | ||||
|             break; | ||||
|     case 0xF8: | ||||
|         fcmd = data; | ||||
|         fcommand(); | ||||
|         break; | ||||
|     case 0xF9: | ||||
|         fdat = data; | ||||
|         break; | ||||
|     case 0xFA: | ||||
|         fbuf[0] = data; | ||||
|         break; | ||||
|     case 0xFB: | ||||
|         fbuf[1] = data; | ||||
|         break; | ||||
|     case 0xFC: | ||||
|         fbuf[2] = data; | ||||
|         break; | ||||
|     case 0xFD: | ||||
|         fbuf[3] = data; | ||||
|         break; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -7,8 +7,8 @@ | ||||
| struct battery_info battery_info = { 0 }; | ||||
|  | ||||
| // Default values to disable battery charging thresholds | ||||
| #define BATTERY_START_DEFAULT   0 | ||||
| #define BATTERY_END_DEFAULT     100 | ||||
| #define BATTERY_START_DEFAULT 0 | ||||
| #define BATTERY_END_DEFAULT 100 | ||||
|  | ||||
| // Represents a battery percentage level, below which charging will begin. | ||||
| // Valid values are [0, 100] | ||||
| @@ -57,16 +57,13 @@ int16_t battery_charger_configure(void) { | ||||
|     if (battery_get_end_threshold() == BATTERY_END_DEFAULT) { | ||||
|         // Stop threshold not configured: Always charge on AC. | ||||
|         should_charge = true; | ||||
|     } | ||||
|     else if (battery_info.charge > battery_get_end_threshold()) { | ||||
|     } else if (battery_info.charge > battery_get_end_threshold()) { | ||||
|         // Stop threshold configured: Stop charging at threshold. | ||||
|         should_charge = false; | ||||
|     } | ||||
|     else if (battery_get_start_threshold() == BATTERY_START_DEFAULT) { | ||||
|     } else if (battery_get_start_threshold() == BATTERY_START_DEFAULT) { | ||||
|         // Start threshold not configured: Always charge up to stop threshold. | ||||
|         should_charge = true; | ||||
|     } | ||||
|     else if (battery_info.charge < battery_get_start_threshold()) { | ||||
|     } else if (battery_info.charge < battery_get_start_threshold()) { | ||||
|         // Start threshold configured: Start charging at threshold. | ||||
|         should_charge = true; | ||||
|     } | ||||
| @@ -79,7 +76,8 @@ int16_t battery_charger_configure(void) { | ||||
| void battery_event(void) { | ||||
|     int16_t res = 0; | ||||
|  | ||||
|     #define command(N, V) { \ | ||||
| #define command(N, V) \ | ||||
|     { \ | ||||
|         res = smbus_read(BATTERY_ADDRESS, V, &N); \ | ||||
|         if (res < 0) { \ | ||||
|             N = 0; \ | ||||
| @@ -97,7 +95,7 @@ void battery_event(void) { | ||||
|     command(battery_info.design_capacity, 0x18); | ||||
|     command(battery_info.design_voltage, 0x19); | ||||
|  | ||||
|     #undef command | ||||
| #undef command | ||||
|  | ||||
|     TRACE("BAT %d mV %d mA\n", battery_info.voltage, battery_info.current); | ||||
|  | ||||
|   | ||||
| @@ -8,6 +8,8 @@ | ||||
| #include <common/macro.h> | ||||
| #include <common/debug.h> | ||||
|  | ||||
| // clang-format off | ||||
|  | ||||
| // Registers | ||||
| #define REG_CHARGE_CURRENT 0x14 | ||||
| #define REG_CHARGE_VOLTAGE 0x15 | ||||
| @@ -40,7 +42,6 @@ | ||||
| // Battery depletion threshold | ||||
| #define SBC_BAT_DEPL_VTH    (0b11 << 14) | ||||
|  | ||||
|  | ||||
| // Bits 0-5 are ignored. Bits 13-15 must be 0. | ||||
| #define CHARGE_CURRENT_MASK 0x1FC0 | ||||
|  | ||||
| @@ -85,35 +86,38 @@ | ||||
|     #error Invalid adapter:battery RSENSE ratio | ||||
| #endif | ||||
|  | ||||
| // clang-format on | ||||
|  | ||||
| // XXX: Assumption: ac_last is initialized high. | ||||
| static bool charger_enabled = false; | ||||
|  | ||||
| int16_t battery_charger_disable(void) { | ||||
|     int16_t res = 0; | ||||
|  | ||||
|     if (!charger_enabled) return 0; | ||||
|     if (!charger_enabled) | ||||
|         return 0; | ||||
|  | ||||
|     // Set charge option 0 with 175s watchdog | ||||
|     res = smbus_write( | ||||
|         CHARGER_ADDRESS, | ||||
|         REG_CHARGE_OPTION_0, | ||||
|         SBC_EN_LWPWR | | ||||
|         SBC_WDTMR_ADJ_175S | | ||||
|         SBC_PWM_FREQ_800KHZ | | ||||
|         SBC_IDCHC_GAIN | ||||
|         SBC_EN_LWPWR | SBC_WDTMR_ADJ_175S | SBC_PWM_FREQ_800KHZ | SBC_IDCHC_GAIN | ||||
|     ); | ||||
|  | ||||
|     // Disable charge current | ||||
|     res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_CURRENT, 0); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     // Disable charge voltage | ||||
|     res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_VOLTAGE, 0); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     // Disable input current | ||||
|     res = smbus_write(CHARGER_ADDRESS, REG_INPUT_CURRENT, 0); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     DEBUG("Charger disabled\n"); | ||||
|     charger_enabled = false; | ||||
| @@ -123,40 +127,40 @@ int16_t battery_charger_disable(void) { | ||||
| int16_t battery_charger_enable(void) { | ||||
|     int16_t res = 0; | ||||
|  | ||||
|     if (charger_enabled) return 0; | ||||
|     if (charger_enabled) | ||||
|         return 0; | ||||
|  | ||||
|     res = battery_charger_disable(); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     // Set charge current in mA | ||||
|     res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_CURRENT, CHARGE_CURRENT); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     // Set charge voltage in mV | ||||
|     res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_VOLTAGE, CHARGE_VOLTAGE); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     // Set input current in mA | ||||
|     res = smbus_write(CHARGER_ADDRESS, REG_INPUT_CURRENT, INPUT_CURRENT); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     // Set charge option 0 with watchdog disabled | ||||
|     res = smbus_write( | ||||
|         CHARGER_ADDRESS, | ||||
|         REG_CHARGE_OPTION_0, | ||||
|         SBC_EN_LWPWR | | ||||
|         SBC_PWM_FREQ_800KHZ | | ||||
|         SBC_IDCHC_GAIN | ||||
|         SBC_EN_LWPWR | SBC_PWM_FREQ_800KHZ | SBC_IDCHC_GAIN | ||||
|     ); | ||||
|  | ||||
|     // Set the RSENSE ratio | ||||
|     res = smbus_write( | ||||
|         CHARGER_ADDRESS, | ||||
|         REG_CHARGE_OPTION_1, | ||||
|         SBC_CMP_DEG_1US | | ||||
|         SBC_PMON_RATIO | | ||||
|         RSENSE_RATIO | | ||||
|         SBC_BAT_DEPL_VTH | ||||
|         SBC_CMP_DEG_1US | SBC_PMON_RATIO | RSENSE_RATIO | SBC_BAT_DEPL_VTH | ||||
|     ); | ||||
|  | ||||
|     DEBUG("Charger enabled\n"); | ||||
| @@ -172,7 +176,8 @@ void battery_debug(void) { | ||||
|     uint16_t data = 0; | ||||
|     int16_t res = 0; | ||||
|  | ||||
|     #define command(N, A, V) { \ | ||||
| #define command(N, A, V) \ | ||||
|     { \ | ||||
|         DEBUG("  " #N ": "); \ | ||||
|         res = smbus_read(A, V, &data); \ | ||||
|         if (res < 0) { \ | ||||
| @@ -202,5 +207,5 @@ void battery_debug(void) { | ||||
|     command(ProchotOption1, CHARGER_ADDRESS, 0x3D); | ||||
|     command(ProchotStatus, CHARGER_ADDRESS, 0x3A); | ||||
|  | ||||
|     #undef command | ||||
| #undef command | ||||
| } | ||||
|   | ||||
| @@ -8,6 +8,8 @@ | ||||
| #include <common/debug.h> | ||||
| #include <common/macro.h> | ||||
|  | ||||
| // clang-format off | ||||
|  | ||||
| // Registers | ||||
| #define REG_CHARGE_CURRENT 0x14 | ||||
| #define REG_CHARGE_VOLTAGE 0x15 | ||||
| @@ -54,6 +56,8 @@ | ||||
|     #error Invalid adapter RSENSE value | ||||
| #endif | ||||
|  | ||||
| // clang-format on | ||||
|  | ||||
| // Sense resistor values in milliohms. | ||||
| enum sense_resistor { | ||||
|     RSENSE_10 = 0, | ||||
| @@ -67,7 +71,8 @@ static bool charger_enabled = false; | ||||
| int16_t battery_charger_disable(void) { | ||||
|     int16_t res = 0; | ||||
|  | ||||
|     if (!charger_enabled) return 0; | ||||
|     if (!charger_enabled) | ||||
|         return 0; | ||||
|  | ||||
|     // Set charge option 1 to converter frequency 600 KHz | ||||
|     //TODO: needed when charging disabled? | ||||
| @@ -76,29 +81,30 @@ int16_t battery_charger_disable(void) { | ||||
|         REG_CHARGE_OPTION_1, | ||||
|         CHARGE_OPTION_1_600KHZ | ADAPTER_RSENSE | BATTERY_RSENSE | ||||
|     ); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     // Set charge option 2 to PSYS enable | ||||
|     //TODO: needed when charging disabled? | ||||
|     res = smbus_write( | ||||
|         CHARGER_ADDRESS, | ||||
|         REG_CHARGE_OPTION_2, | ||||
|         CHARGE_OPTION_2_PSYS_EN | ||||
|     ); | ||||
|     if (res < 0) return res; | ||||
|     res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_OPTION_2, CHARGE_OPTION_2_PSYS_EN); | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     // Disable charge current | ||||
|     res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_CURRENT, 0); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     // Disable charge voltage | ||||
|     res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_VOLTAGE, 0); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     // Set input current in mA | ||||
|     //TODO: needed when charging disabled? | ||||
|     res = smbus_write(CHARGER_ADDRESS, REG_ADAPTER_CURRENT, INPUT_CURRENT); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     DEBUG("Charger disabled\n"); | ||||
|     charger_enabled = false; | ||||
| @@ -108,10 +114,12 @@ int16_t battery_charger_disable(void) { | ||||
| int16_t battery_charger_enable(void) { | ||||
|     int16_t res = 0; | ||||
|  | ||||
|     if (charger_enabled) return 0; | ||||
|     if (charger_enabled) | ||||
|         return 0; | ||||
|  | ||||
|     res = battery_charger_disable(); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     // Set charge option 1 to converter frequency 600 KHz | ||||
|     res = smbus_write( | ||||
| @@ -119,27 +127,28 @@ int16_t battery_charger_enable(void) { | ||||
|         REG_CHARGE_OPTION_1, | ||||
|         CHARGE_OPTION_1_600KHZ | ADAPTER_RSENSE | BATTERY_RSENSE | ||||
|     ); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     // Set charge option 2 to PSYS enable | ||||
|     res = smbus_write( | ||||
|         CHARGER_ADDRESS, | ||||
|         REG_CHARGE_OPTION_2, | ||||
|         CHARGE_OPTION_2_PSYS_EN | ||||
|     ); | ||||
|     if (res < 0) return res; | ||||
|     res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_OPTION_2, CHARGE_OPTION_2_PSYS_EN); | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     // Set charge current in mA | ||||
|     res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_CURRENT, CHARGE_CURRENT); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     // Set charge voltage in mV | ||||
|     res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_VOLTAGE, CHARGE_VOLTAGE); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     // Set input current in mA | ||||
|     res = smbus_write(CHARGER_ADDRESS, REG_ADAPTER_CURRENT, INPUT_CURRENT); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     DEBUG("Charger enabled\n"); | ||||
|     charger_enabled = true; | ||||
| @@ -158,7 +167,8 @@ void battery_debug(void) { | ||||
|     uint16_t data = 0; | ||||
|     int16_t res = 0; | ||||
|  | ||||
|     #define command(N, A, V) { \ | ||||
| #define command(N, A, V) \ | ||||
|     { \ | ||||
|         DEBUG("  " #N ": "); \ | ||||
|         res = smbus_read(A, V, &data); \ | ||||
|         if (res < 0) { \ | ||||
| @@ -182,5 +192,5 @@ void battery_debug(void) { | ||||
|     command(ChargeOption_2, CHARGER_ADDRESS, REG_CHARGE_OPTION_2); | ||||
|     command(AdapterCurrent, CHARGER_ADDRESS, REG_ADAPTER_CURRENT); | ||||
|  | ||||
|     #undef command | ||||
| #undef command | ||||
| } | ||||
|   | ||||
| @@ -15,14 +15,14 @@ | ||||
|  | ||||
| // Fan speed is the lowest requested over HEATUP seconds | ||||
| #ifndef BOARD_DGPU_HEATUP | ||||
|     #define BOARD_DGPU_HEATUP 4 | ||||
| #define BOARD_DGPU_HEATUP 4 | ||||
| #endif | ||||
|  | ||||
| static uint8_t FAN_HEATUP[BOARD_DGPU_HEATUP] = { 0 }; | ||||
|  | ||||
| // Fan speed is the highest HEATUP speed over COOLDOWN seconds | ||||
| #ifndef BOARD_DGPU_COOLDOWN | ||||
|     #define BOARD_DGPU_COOLDOWN 10 | ||||
| #define BOARD_DGPU_COOLDOWN 10 | ||||
| #endif | ||||
|  | ||||
| static uint8_t FAN_COOLDOWN[BOARD_DGPU_COOLDOWN] = { 0 }; | ||||
| @@ -31,7 +31,8 @@ int16_t dgpu_temp = 0; | ||||
|  | ||||
| #define DGPU_TEMP(X) ((int16_t)(X)) | ||||
|  | ||||
| #define FAN_POINT(T, D) { .temp = DGPU_TEMP(T), .duty = PWM_DUTY(D) } | ||||
| #define FAN_POINT(T, D) \ | ||||
|     { .temp = DGPU_TEMP(T), .duty = PWM_DUTY(D) } | ||||
|  | ||||
| // Fan curve with temperature in degrees C, duty cycle in percent | ||||
| static struct FanPoint __code FAN_POINTS[] = { | ||||
| @@ -100,7 +101,7 @@ uint8_t dgpu_get_fan_duty(void) { | ||||
| void dgpu_init(void) {} | ||||
|  | ||||
| uint8_t dgpu_get_fan_duty(void) { | ||||
|   return PWM_DUTY(0); | ||||
|     return PWM_DUTY(0); | ||||
| } | ||||
|  | ||||
| #endif // HAVE_DGPU | ||||
|   | ||||
| @@ -13,36 +13,32 @@ | ||||
| #include <8051.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| #define DEBUG_SET(REG, MASK, BITS) { \ | ||||
|     DEBUG("%s: %X", #REG, REG); \ | ||||
|     REG = ((REG) & ~(MASK)) | (BITS); \ | ||||
|     DEBUG(" set to %X\n", REG); \ | ||||
| } | ||||
| #define DEBUG_SET(REG, MASK, BITS) \ | ||||
|     { \ | ||||
|         DEBUG("%s: %X", #REG, REG); \ | ||||
|         REG = ((REG) & ~(MASK)) | (BITS); \ | ||||
|         DEBUG(" set to %X\n", REG); \ | ||||
|     } | ||||
|  | ||||
| #define DEBUG_ON(REG, BITS) \ | ||||
|     DEBUG_SET(REG, BITS, BITS) | ||||
| #define DEBUG_ON(REG, BITS) DEBUG_SET(REG, BITS, BITS) | ||||
|  | ||||
| #define DEBUG_OFF(REG, BITS) \ | ||||
|     DEBUG_SET(REG, BITS, 0) | ||||
| #define DEBUG_OFF(REG, BITS) DEBUG_SET(REG, BITS, 0) | ||||
|  | ||||
| #define DEBUG_CHANGED(REG) { \ | ||||
|     static uint8_t last_ ## REG = 0; \ | ||||
|     uint8_t new_ ## REG = REG; \ | ||||
|     if (new_ ## REG != last_ ## REG) { \ | ||||
|         DEBUG( \ | ||||
|             "%S: %X changed to %X\n", \ | ||||
|             #REG, \ | ||||
|             last_ ## REG, \ | ||||
|             new_ ## REG \ | ||||
|         ); \ | ||||
|         last_ ## REG = new_ ## REG; \ | ||||
|     } \ | ||||
| } | ||||
| #define DEBUG_CHANGED(REG) \ | ||||
|     { \ | ||||
|         static uint8_t last_##REG = 0; \ | ||||
|         uint8_t new_##REG = REG; \ | ||||
|         if (new_##REG != last_##REG) { \ | ||||
|             DEBUG("%S: %X changed to %X\n", #REG, last_##REG, new_##REG); \ | ||||
|             last_##REG = new_##REG; \ | ||||
|         } \ | ||||
|     } | ||||
|  | ||||
| #define VW_SET_DEBUG(W, V) { \ | ||||
|     DEBUG("%s = %X\n", #W, V); \ | ||||
|     vw_set(&W, V); \ | ||||
| } | ||||
| #define VW_SET_DEBUG(W, V) \ | ||||
|     { \ | ||||
|         DEBUG("%s = %X\n", #W, V); \ | ||||
|         vw_set(&W, V); \ | ||||
|     } | ||||
|  | ||||
| void espi_init(void) { | ||||
|     if (PLLFREQ != 0b0111) { | ||||
|   | ||||
| @@ -25,9 +25,9 @@ void fan_reset(void) { | ||||
|  | ||||
| // Get duty cycle based on temperature, adapted from | ||||
| // https://github.com/pop-os/system76-power/blob/master/src/fan.rs | ||||
| uint8_t fan_duty(const struct Fan * fan, int16_t temp) __reentrant { | ||||
| uint8_t fan_duty(const struct Fan *fan, int16_t temp) __reentrant { | ||||
|     for (uint8_t i = 0; i < fan->points_size; i++) { | ||||
|         const struct FanPoint * cur = &fan->points[i]; | ||||
|         const struct FanPoint *cur = &fan->points[i]; | ||||
|  | ||||
|         // If exactly the current temp, return the current duty | ||||
|         if (temp == cur->temp) { | ||||
| @@ -37,17 +37,19 @@ uint8_t fan_duty(const struct Fan * fan, int16_t temp) __reentrant { | ||||
|             if (i == 0) { | ||||
|                 return MIN_FAN_SPEED; | ||||
|             } else { | ||||
|                 const struct FanPoint * prev = &fan->points[i - 1]; | ||||
|                 const struct FanPoint *prev = &fan->points[i - 1]; | ||||
|  | ||||
|                 if (fan->interpolate) { | ||||
|                     // If in between current temp and previous temp, interpolate | ||||
|                     if (temp > prev->temp) { | ||||
|                         int16_t dtemp = (cur->temp - prev->temp); | ||||
|                         int16_t dduty = ((int16_t)cur->duty) - ((int16_t)prev->duty); | ||||
|                         // clang-format off | ||||
|                         return (uint8_t)( | ||||
|                             ((int16_t)prev->duty) + | ||||
|                             ((temp - prev->temp) * dduty) / dtemp | ||||
|                         ); | ||||
|                         // clang-format on | ||||
|                     } | ||||
|                 } else { | ||||
|                     return prev->duty; | ||||
| @@ -61,10 +63,10 @@ uint8_t fan_duty(const struct Fan * fan, int16_t temp) __reentrant { | ||||
| } | ||||
|  | ||||
| void fan_duty_set(uint8_t peci_fan_duty, uint8_t dgpu_fan_duty) __reentrant { | ||||
|     #if SYNC_FANS != 0 | ||||
|         peci_fan_duty = peci_fan_duty > dgpu_fan_duty ? peci_fan_duty : dgpu_fan_duty; | ||||
|         dgpu_fan_duty = peci_fan_duty > dgpu_fan_duty ? peci_fan_duty : dgpu_fan_duty; | ||||
|     #endif | ||||
| #if SYNC_FANS != 0 | ||||
|     peci_fan_duty = peci_fan_duty > dgpu_fan_duty ? peci_fan_duty : dgpu_fan_duty; | ||||
|     dgpu_fan_duty = peci_fan_duty > dgpu_fan_duty ? peci_fan_duty : dgpu_fan_duty; | ||||
| #endif | ||||
|  | ||||
|     // set PECI fan duty | ||||
|     if (peci_fan_duty != DCR2) { | ||||
| @@ -83,7 +85,7 @@ void fan_duty_set(uint8_t peci_fan_duty, uint8_t dgpu_fan_duty) __reentrant { | ||||
|     } | ||||
| } | ||||
|  | ||||
| uint8_t fan_heatup(const struct Fan * fan, uint8_t duty) __reentrant { | ||||
| uint8_t fan_heatup(const struct Fan *fan, uint8_t duty) __reentrant { | ||||
|     uint8_t lowest = duty; | ||||
|  | ||||
|     uint8_t i; | ||||
| @@ -99,7 +101,7 @@ uint8_t fan_heatup(const struct Fan * fan, uint8_t duty) __reentrant { | ||||
|     return lowest; | ||||
| } | ||||
|  | ||||
| uint8_t fan_cooldown(const struct Fan * fan, uint8_t duty) __reentrant { | ||||
| uint8_t fan_cooldown(const struct Fan *fan, uint8_t duty) __reentrant { | ||||
|     uint8_t highest = duty; | ||||
|  | ||||
|     uint8_t i; | ||||
| @@ -121,9 +123,11 @@ uint8_t fan_smooth(uint8_t last_duty, uint8_t duty) __reentrant { | ||||
|     // ramping down | ||||
|     if (duty < last_duty) { | ||||
|         // out of bounds (lower) safeguard | ||||
|         // clang-format off | ||||
|         uint8_t smoothed = last_duty < MIN_FAN_SPEED + MAX_JUMP_DOWN | ||||
|             ? MIN_FAN_SPEED | ||||
|             : last_duty - MAX_JUMP_DOWN; | ||||
|         // clang-format on | ||||
|  | ||||
|         // use smoothed value if above min and if smoothed is closer than raw | ||||
|         if (last_duty > MIN_SPEED_TO_SMOOTH && smoothed > duty) { | ||||
| @@ -134,9 +138,11 @@ uint8_t fan_smooth(uint8_t last_duty, uint8_t duty) __reentrant { | ||||
|     // ramping up | ||||
|     if (duty > last_duty) { | ||||
|         // out of bounds (higher) safeguard | ||||
|         // clang-format off | ||||
|         uint8_t smoothed = last_duty > MAX_FAN_SPEED - MAX_JUMP_UP | ||||
|             ? MAX_FAN_SPEED | ||||
|             : last_duty + MAX_JUMP_UP; | ||||
|         // clang-format on | ||||
|  | ||||
|         // use smoothed value if above min and if smoothed is closer than raw | ||||
|         if (duty > MIN_SPEED_TO_SMOOTH && smoothed < duty) { | ||||
|   | ||||
| @@ -3,6 +3,6 @@ | ||||
| #ifndef _FLASH_ENTRY_H | ||||
| #define _FLASH_ENTRY_H | ||||
|  | ||||
| void flash_entry(uint32_t addr, uint8_t * data, uint32_t length, uint8_t command) __reentrant; | ||||
| void flash_entry(uint32_t addr, uint8_t *data, uint32_t length, uint8_t command) __reentrant; | ||||
|  | ||||
| #endif // _FLASH_ENTRY_H | ||||
|   | ||||
| @@ -15,6 +15,7 @@ volatile uint8_t __xdata __at(0x103D) ECINDAR2; | ||||
| volatile uint8_t __xdata __at(0x103E) ECINDAR3; | ||||
| volatile uint8_t __xdata __at(0x103F) ECINDDR; | ||||
|  | ||||
| // clang-format off | ||||
| #define SPI_DEVICE                  (0x70) | ||||
| #define SPI_FOLLOW_MODE             (0x0F) | ||||
| #define SPI_CHIP_SELECT             (0xFD) | ||||
| @@ -29,6 +30,7 @@ volatile uint8_t __xdata __at(0x103F) ECINDDR; | ||||
| #define SPI_ERASE_SECTOR_COMMAND    (0xD7) | ||||
|  | ||||
| #define SPI_STATUS_WIP              (0x01) | ||||
| // clang-format on | ||||
|  | ||||
| void flash_enter_follow_mode(void); | ||||
| void flash_exit_follow_mode(void); | ||||
| @@ -46,11 +48,11 @@ void flash_write_enable(void); | ||||
|  * NOTE: __critical to ensure interrupts are disabled. This does mean that interrupt | ||||
|  *          such as the timer will be block until flash acccess is complete | ||||
|  */ | ||||
| void flash_entry(uint32_t addr, uint8_t * data, uint32_t length, uint8_t command) __reentrant __critical { | ||||
| // clang-format off | ||||
| void flash_entry(uint32_t addr, uint8_t *data, uint32_t length, uint8_t command) __reentrant __critical { | ||||
|     // clang-format on | ||||
|     // Only allow access from 64KB to 128KB. | ||||
|     if ((addr < 0x10000) | ||||
|     || (length > 0x10000) | ||||
|     || ((addr + length) > 0x20000)) | ||||
|     if ((addr < 0x10000) || (length > 0x10000) || ((addr + length) > 0x20000)) | ||||
|         return; | ||||
|  | ||||
|     if (command == FLASH_COMMAND_READ) { | ||||
| @@ -91,8 +93,7 @@ void flash_entry(uint32_t addr, uint8_t * data, uint32_t length, uint8_t command | ||||
|  | ||||
|             // Deselect | ||||
|             ECINDAR1 = SPI_CHIP_DESELECT; | ||||
|             ECINDDR  = 0x00; | ||||
|  | ||||
|             ECINDDR = 0x00; | ||||
|  | ||||
|             // Wait WIP to be cleared | ||||
|             flash_wait(); | ||||
| @@ -115,7 +116,7 @@ void flash_entry(uint32_t addr, uint8_t * data, uint32_t length, uint8_t command | ||||
|  | ||||
|         // Deselect | ||||
|         ECINDAR1 = SPI_CHIP_DESELECT; | ||||
|         ECINDDR  = 0x00; | ||||
|         ECINDDR = 0x00; | ||||
|  | ||||
|         // Wait WIP to be cleared | ||||
|         flash_wait(); | ||||
| @@ -156,8 +157,8 @@ void flash_wait(void) { | ||||
|  | ||||
|         // Deselect | ||||
|         ECINDAR1 = SPI_CHIP_DESELECT; | ||||
|         ECINDDR  = 0x00; | ||||
|     } while(status & SPI_STATUS_WIP); | ||||
|         ECINDDR = 0x00; | ||||
|     } while (status & SPI_STATUS_WIP); | ||||
| } | ||||
|  | ||||
| void flash_write_enable(void) { | ||||
| @@ -169,5 +170,5 @@ void flash_write_enable(void) { | ||||
|  | ||||
|     // Deselect | ||||
|     ECINDAR1 = SPI_CHIP_DESELECT; | ||||
|     ECINDDR  = 0x00; | ||||
|     ECINDDR = 0x00; | ||||
| } | ||||
|   | ||||
| @@ -12,10 +12,10 @@ | ||||
|  | ||||
| // Include flash ROM | ||||
| uint8_t __code __at(FLASH_OFFSET) flash_rom[] = { | ||||
|     #include <flash.h> | ||||
| #include <flash.h> | ||||
| }; | ||||
|  | ||||
| static void flash_api(uint32_t addr, uint8_t * data, uint32_t length, uint8_t command) { | ||||
| static void flash_api(uint32_t addr, uint8_t *data, uint32_t length, uint8_t command) { | ||||
|     // Use DMA mapping to copy flash ROM to scratch ROM | ||||
|     SCARH = 0x80; | ||||
|     SCARL = (uint8_t)(FLASH_OFFSET); | ||||
| @@ -29,7 +29,7 @@ static void flash_api(uint32_t addr, uint8_t * data, uint32_t length, uint8_t co | ||||
|     SCARH = 0x07; | ||||
| } | ||||
|  | ||||
| void flash_read(uint32_t addr, __xdata uint8_t * data, uint32_t length) { | ||||
| void flash_read(uint32_t addr, __xdata uint8_t *data, uint32_t length) { | ||||
|     flash_api(addr, data, length, FLASH_COMMAND_READ); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -7,11 +7,11 @@ | ||||
|  | ||||
| enum EcOs { | ||||
|     // No ACPI or driver support | ||||
|     EC_OS_NONE=0, | ||||
|     EC_OS_NONE = 0, | ||||
|     // ACPI, but no driver support | ||||
|     EC_OS_ACPI=1, | ||||
|     EC_OS_ACPI = 1, | ||||
|     // ACPI with driver, full support | ||||
|     EC_OS_FULL=2, | ||||
|     EC_OS_FULL = 2, | ||||
| }; | ||||
| extern enum EcOs acpi_ecos; | ||||
|  | ||||
|   | ||||
| @@ -9,11 +9,11 @@ | ||||
| #include <stdint.h> | ||||
|  | ||||
| #ifndef BATTERY_ADDRESS | ||||
|     #define BATTERY_ADDRESS 0x0B | ||||
| #define BATTERY_ADDRESS 0x0B | ||||
| #endif | ||||
|  | ||||
| #ifndef CHARGER_ADDRESS | ||||
|     #define CHARGER_ADDRESS 0x09 | ||||
| #define CHARGER_ADDRESS 0x09 | ||||
| #endif | ||||
|  | ||||
| #define BATTERY_INITIALIZED BIT(7) | ||||
|   | ||||
| @@ -6,11 +6,11 @@ | ||||
| #include <stdint.h> | ||||
|  | ||||
| #ifndef HAVE_DGPU | ||||
|     #define HAVE_DGPU 0 | ||||
| #define HAVE_DGPU 0 | ||||
| #endif | ||||
|  | ||||
| #if HAVE_DGPU | ||||
|     extern int16_t dgpu_temp; | ||||
| extern int16_t dgpu_temp; | ||||
| #endif // HAVE_DGPU | ||||
|  | ||||
| void dgpu_init(void); | ||||
|   | ||||
| @@ -11,24 +11,24 @@ | ||||
| #define MIN_FAN_SPEED PWM_DUTY(0) | ||||
|  | ||||
| #ifndef SMOOTH_FANS | ||||
|     #define SMOOTH_FANS 1 // default to fan smoothing | ||||
| #define SMOOTH_FANS 1 // default to fan smoothing | ||||
| #endif | ||||
|  | ||||
| #ifndef SYNC_FANS | ||||
|     #define SYNC_FANS 1 // default to syncing fan speeds | ||||
| #define SYNC_FANS 1 // default to syncing fan speeds | ||||
| #endif | ||||
|  | ||||
| #if SMOOTH_FANS != 0 | ||||
|     #ifndef SMOOTH_FANS_UP | ||||
|         #define SMOOTH_FANS_UP 45 // default to ~11 seconds for full ramp-up | ||||
|     #endif | ||||
|     #ifndef SMOOTH_FANS_DOWN | ||||
|         #define SMOOTH_FANS_DOWN 100 // default to ~25 seconds for full ramp-down | ||||
|     #endif | ||||
| #ifndef SMOOTH_FANS_UP | ||||
| #define SMOOTH_FANS_UP 45 // default to ~11 seconds for full ramp-up | ||||
| #endif | ||||
| #ifndef SMOOTH_FANS_DOWN | ||||
| #define SMOOTH_FANS_DOWN 100 // default to ~25 seconds for full ramp-down | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| #ifndef SMOOTH_FANS_MIN | ||||
|     #define SMOOTH_FANS_MIN 0 // default to smoothing all fan speed changes | ||||
| #define SMOOTH_FANS_MIN 0 // default to smoothing all fan speed changes | ||||
| #endif | ||||
|  | ||||
| struct FanPoint { | ||||
| @@ -37,11 +37,11 @@ struct FanPoint { | ||||
| }; | ||||
|  | ||||
| struct Fan { | ||||
|     const struct FanPoint * points; | ||||
|     const struct FanPoint *points; | ||||
|     uint8_t points_size; | ||||
|     uint8_t * heatup; | ||||
|     uint8_t *heatup; | ||||
|     uint8_t heatup_size; | ||||
|     uint8_t * cooldown; | ||||
|     uint8_t *cooldown; | ||||
|     uint8_t cooldown_size; | ||||
|     bool interpolate; | ||||
| }; | ||||
| @@ -50,10 +50,10 @@ extern bool fan_max; | ||||
|  | ||||
| void fan_reset(void); | ||||
|  | ||||
| uint8_t fan_duty(const struct Fan * fan, int16_t temp) __reentrant; | ||||
| uint8_t fan_duty(const struct Fan *fan, int16_t temp) __reentrant; | ||||
| void fan_duty_set(uint8_t peci_fan_duty, uint8_t dgpu_fan_duty) __reentrant; | ||||
| uint8_t fan_heatup(const struct Fan * fan, uint8_t duty) __reentrant; | ||||
| uint8_t fan_cooldown(const struct Fan * fan, uint8_t duty) __reentrant; | ||||
| uint8_t fan_heatup(const struct Fan *fan, uint8_t duty) __reentrant; | ||||
| uint8_t fan_cooldown(const struct Fan *fan, uint8_t duty) __reentrant; | ||||
| uint8_t fan_smooth(uint8_t last_duty, uint8_t duty) __reentrant; | ||||
|  | ||||
| #endif // _BOARD_FAN_H | ||||
|   | ||||
| @@ -12,9 +12,11 @@ | ||||
| /** \cond INTERNAL | ||||
|  * Internal defines | ||||
|  */ | ||||
| // clang-format off | ||||
| #define FLASH_COMMAND_READ      (0x0) | ||||
| #define FLASH_COMMAND_WRITE     (0x1) | ||||
| #define FLASH_COMMAND_ERASE_1K  (0x2) | ||||
| // clang-format on | ||||
| /** \endcond */ | ||||
|  | ||||
| /** | ||||
| @@ -24,7 +26,7 @@ | ||||
|  * \param[out] data   The memory area to copy to. | ||||
|  * \param[in]  length The number of bytes to copy. | ||||
|  */ | ||||
| void flash_read(uint32_t addr, __xdata uint8_t * data, uint32_t length); | ||||
| void flash_read(uint32_t addr, __xdata uint8_t *data, uint32_t length); | ||||
|  | ||||
| /** | ||||
|  * Read a single byte from flash. | ||||
| @@ -60,7 +62,7 @@ uint32_t flash_read_u32(uint32_t addr); | ||||
|  * \param[in] data   The memory area to copy from. | ||||
|  * \param[in] length The number of bytes to copy. | ||||
|  */ | ||||
| void flash_write(uint32_t addr, __xdata uint8_t * data, uint32_t length); | ||||
| void flash_write(uint32_t addr, __xdata uint8_t *data, uint32_t length); | ||||
|  | ||||
| /** | ||||
|  * Write a single byte to flash. | ||||
|   | ||||
| @@ -11,6 +11,6 @@ extern uint8_t kbc_leds; | ||||
|  | ||||
| void kbc_init(void); | ||||
| bool kbc_scancode(uint16_t key, bool pressed); | ||||
| void kbc_event(struct Kbc * kbc); | ||||
| void kbc_event(struct Kbc *kbc); | ||||
|  | ||||
| #endif // _BOARD_KBC_H | ||||
|   | ||||
| @@ -8,6 +8,6 @@ | ||||
|  | ||||
| extern bool parallel_debug; | ||||
| bool parallel_init(void); | ||||
| int16_t parallel_write(uint8_t * data, uint16_t length); | ||||
| int16_t parallel_write(uint8_t *data, uint16_t length); | ||||
|  | ||||
| #endif // _BOARD_PARALLEL_H | ||||
|   | ||||
| @@ -6,8 +6,8 @@ | ||||
| #include <ec/pmc.h> | ||||
|  | ||||
| void pmc_init(void); | ||||
| bool pmc_sci(struct Pmc * pmc, uint8_t sci); | ||||
| bool pmc_sci(struct Pmc *pmc, uint8_t sci); | ||||
| void pmc_swi(void); | ||||
| void pmc_event(struct Pmc * pmc); | ||||
| void pmc_event(struct Pmc *pmc); | ||||
|  | ||||
| #endif // _BOARD_PMC_H | ||||
|   | ||||
| @@ -6,7 +6,7 @@ | ||||
| #include <ec/smbus.h> | ||||
|  | ||||
| void smbus_init(void); | ||||
| int16_t smbus_read(uint8_t address, uint8_t command, uint16_t * data); | ||||
| int16_t smbus_read(uint8_t address, uint8_t command, uint16_t *data); | ||||
| int16_t smbus_write(uint8_t address, uint8_t command, uint16_t data); | ||||
|  | ||||
| #endif // _BOARD_SMBUS_H | ||||
|   | ||||
| @@ -36,6 +36,7 @@ static bool kbc_translate = true; | ||||
| // LED state | ||||
| uint8_t kbc_leds = 0; | ||||
|  | ||||
| // clang-format off | ||||
| // Values from linux/drivers/input/keyboard/atkbd.c | ||||
| static const uint16_t kbc_typematic_period[32] = { | ||||
|     33,     // 30.0 cps = ~33.33ms | ||||
| @@ -71,12 +72,13 @@ static const uint16_t kbc_typematic_period[32] = { | ||||
|     470,    //  2.1 cps = ~478.19ms | ||||
|     500,    //  2.0 cps = 500ms | ||||
| }; | ||||
| // clang-format on | ||||
|  | ||||
| static uint8_t kbc_buffer[16] = { 0 }; | ||||
| static uint8_t kbc_buffer_head = 0; | ||||
| static uint8_t kbc_buffer_tail = 0; | ||||
|  | ||||
| static bool kbc_buffer_pop(uint8_t * scancode) { | ||||
| static bool kbc_buffer_pop(uint8_t *scancode) { | ||||
|     if (kbc_buffer_head == kbc_buffer_tail) { | ||||
|         return false; | ||||
|     } | ||||
| @@ -85,7 +87,7 @@ static bool kbc_buffer_pop(uint8_t * scancode) { | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| static bool kbc_buffer_push(uint8_t * scancodes, uint8_t len) { | ||||
| static bool kbc_buffer_push(uint8_t *scancodes, uint8_t len) { | ||||
|     //TODO: make this test more efficient | ||||
|     for (uint8_t i = 0; i < len; i++) { | ||||
|         if ((kbc_buffer_tail + i + 1U) % ARRAY_SIZE(kbc_buffer) == kbc_buffer_head) { | ||||
| @@ -101,29 +103,31 @@ static bool kbc_buffer_push(uint8_t * scancodes, uint8_t len) { | ||||
| } | ||||
|  | ||||
| bool kbc_scancode(uint16_t key, bool pressed) { | ||||
|     if (!kbc_first) return true; | ||||
|     if (!kbc_first) | ||||
|         return true; | ||||
|     if (kbc_translate) { | ||||
|         key = keymap_translate(key); | ||||
|     } | ||||
|     if (!key) return true; | ||||
|     if (!key) | ||||
|         return true; | ||||
|  | ||||
|     uint8_t scancodes[3] = {0, 0, 0}; | ||||
|     uint8_t scancodes[3] = { 0, 0, 0 }; | ||||
|     uint8_t scancodes_len = 0; | ||||
|     switch (key & 0xFF00) { | ||||
|         case KF_E0: | ||||
|             scancodes[scancodes_len++] = 0xE0; | ||||
|             key &= 0xFF; | ||||
|             // Fall through | ||||
|         case 0x00: | ||||
|             if (!pressed) { | ||||
|                 if (kbc_translate) { | ||||
|                     key |= 0x80; | ||||
|                 } else { | ||||
|                     scancodes[scancodes_len++] = 0xF0; | ||||
|                 } | ||||
|     case KF_E0: | ||||
|         scancodes[scancodes_len++] = 0xE0; | ||||
|         key &= 0xFF; | ||||
|         // Fall through | ||||
|     case 0x00: | ||||
|         if (!pressed) { | ||||
|             if (kbc_translate) { | ||||
|                 key |= 0x80; | ||||
|             } else { | ||||
|                 scancodes[scancodes_len++] = 0xF0; | ||||
|             } | ||||
|             scancodes[scancodes_len++] = (uint8_t)key; | ||||
|             break; | ||||
|         } | ||||
|         scancodes[scancodes_len++] = (uint8_t)key; | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     return kbc_buffer_push(scancodes, scancodes_len); | ||||
| @@ -156,293 +160,293 @@ static uint8_t state_data = 0; | ||||
| static enum KbcState state_next = KBC_STATE_NORMAL; | ||||
|  | ||||
| // Clear output buffer | ||||
| static void kbc_clear_output(struct Kbc * kbc) { | ||||
| static void kbc_clear_output(struct Kbc *kbc) { | ||||
|     *(kbc->control) |= BIT(5); | ||||
|     *(kbc->control) |= BIT(6); | ||||
|     *(kbc->control) &= ~BIT(5); | ||||
| } | ||||
|  | ||||
| static void kbc_on_input_command(struct Kbc * kbc, uint8_t data) { | ||||
| static void kbc_on_input_command(struct Kbc *kbc, uint8_t data) { | ||||
|     TRACE("kbc cmd: %02X\n", data); | ||||
|     // Controller commands always reset the state | ||||
|     state = KBC_STATE_NORMAL; | ||||
|     // Controller commands clear the output buffer | ||||
|     kbc_clear_output(kbc); | ||||
|     switch (data) { | ||||
|         case 0x20: | ||||
|             TRACE("  read configuration byte\n"); | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             // Interrupt enable flags | ||||
|             state_data = *kbc->control & 0x03; | ||||
|             // System flag | ||||
|             if (*kbc->status & BIT(2)) { | ||||
|                 state_data |= BIT(2); | ||||
|             } | ||||
|             if (!kbc_first) { | ||||
|                 state_data |= BIT(4); | ||||
|             } | ||||
|             if (!kbc_second) { | ||||
|                 state_data |= BIT(5); | ||||
|             } | ||||
|             if (kbc_translate) { | ||||
|                 state_data |= BIT(6); | ||||
|             } | ||||
|             break; | ||||
|         case 0x60: | ||||
|             TRACE("  write configuration byte\n"); | ||||
|             state = KBC_STATE_WRITE_CONFIG; | ||||
|             break; | ||||
|         case 0xA7: | ||||
|             TRACE("  disable second port\n"); | ||||
|             kbc_second = false; | ||||
|             break; | ||||
|         case 0xA8: | ||||
|             TRACE("  enable second port\n"); | ||||
|             kbc_second = true; | ||||
|             break; | ||||
|         case 0xA9: | ||||
|             TRACE("  test second port\n"); | ||||
|             // TODO: communicate with touchpad? | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             state_data = 0x00; | ||||
|             break; | ||||
|         case 0xAA: | ||||
|             TRACE("  test controller\n"); | ||||
|             // Why not pass the test? | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             state_data = 0x55; | ||||
|             break; | ||||
|         case 0xAB: | ||||
|             TRACE("  test first port\n"); | ||||
|             // We _ARE_ the keyboard, so everything is good. | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             state_data = 0x00; | ||||
|             break; | ||||
|         case 0xAD: | ||||
|             TRACE("  disable first port\n"); | ||||
|             kbc_first = false; | ||||
|             break; | ||||
|         case 0xAE: | ||||
|             TRACE("  enable first port\n"); | ||||
|             kbc_first = true; | ||||
|             break; | ||||
|         case 0xD1: | ||||
|             TRACE("  write port byte\n"); | ||||
|             state = KBC_STATE_WRITE_PORT; | ||||
|             break; | ||||
|         case 0xD2: | ||||
|             TRACE("  write first port output\n"); | ||||
|             state = KBC_STATE_FIRST_PORT_OUTPUT; | ||||
|             break; | ||||
|         case 0xD3: | ||||
|             TRACE("  write second port output\n"); | ||||
|             state = KBC_STATE_SECOND_PORT_OUTPUT; | ||||
|             break; | ||||
|         case 0xD4: | ||||
|             TRACE("  write second port input\n"); | ||||
|             state = KBC_STATE_SECOND_PORT_INPUT; | ||||
|             break; | ||||
|     case 0x20: | ||||
|         TRACE("  read configuration byte\n"); | ||||
|         state = KBC_STATE_KEYBOARD; | ||||
|         // Interrupt enable flags | ||||
|         state_data = *kbc->control & 0x03; | ||||
|         // System flag | ||||
|         if (*kbc->status & BIT(2)) { | ||||
|             state_data |= BIT(2); | ||||
|         } | ||||
|         if (!kbc_first) { | ||||
|             state_data |= BIT(4); | ||||
|         } | ||||
|         if (!kbc_second) { | ||||
|             state_data |= BIT(5); | ||||
|         } | ||||
|         if (kbc_translate) { | ||||
|             state_data |= BIT(6); | ||||
|         } | ||||
|         break; | ||||
|     case 0x60: | ||||
|         TRACE("  write configuration byte\n"); | ||||
|         state = KBC_STATE_WRITE_CONFIG; | ||||
|         break; | ||||
|     case 0xA7: | ||||
|         TRACE("  disable second port\n"); | ||||
|         kbc_second = false; | ||||
|         break; | ||||
|     case 0xA8: | ||||
|         TRACE("  enable second port\n"); | ||||
|         kbc_second = true; | ||||
|         break; | ||||
|     case 0xA9: | ||||
|         TRACE("  test second port\n"); | ||||
|         // TODO: communicate with touchpad? | ||||
|         state = KBC_STATE_KEYBOARD; | ||||
|         state_data = 0x00; | ||||
|         break; | ||||
|     case 0xAA: | ||||
|         TRACE("  test controller\n"); | ||||
|         // Why not pass the test? | ||||
|         state = KBC_STATE_KEYBOARD; | ||||
|         state_data = 0x55; | ||||
|         break; | ||||
|     case 0xAB: | ||||
|         TRACE("  test first port\n"); | ||||
|         // We _ARE_ the keyboard, so everything is good. | ||||
|         state = KBC_STATE_KEYBOARD; | ||||
|         state_data = 0x00; | ||||
|         break; | ||||
|     case 0xAD: | ||||
|         TRACE("  disable first port\n"); | ||||
|         kbc_first = false; | ||||
|         break; | ||||
|     case 0xAE: | ||||
|         TRACE("  enable first port\n"); | ||||
|         kbc_first = true; | ||||
|         break; | ||||
|     case 0xD1: | ||||
|         TRACE("  write port byte\n"); | ||||
|         state = KBC_STATE_WRITE_PORT; | ||||
|         break; | ||||
|     case 0xD2: | ||||
|         TRACE("  write first port output\n"); | ||||
|         state = KBC_STATE_FIRST_PORT_OUTPUT; | ||||
|         break; | ||||
|     case 0xD3: | ||||
|         TRACE("  write second port output\n"); | ||||
|         state = KBC_STATE_SECOND_PORT_OUTPUT; | ||||
|         break; | ||||
|     case 0xD4: | ||||
|         TRACE("  write second port input\n"); | ||||
|         state = KBC_STATE_SECOND_PORT_INPUT; | ||||
|         break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void kbc_on_input_data(struct Kbc * kbc, uint8_t data) { | ||||
| static void kbc_on_input_data(struct Kbc *kbc, uint8_t data) { | ||||
|     TRACE("kbc data: %02X\n", data); | ||||
|     switch (state) { | ||||
|         case KBC_STATE_TOUCHPAD: | ||||
|             // Interrupt touchpad command | ||||
|             state = KBC_STATE_NORMAL; | ||||
|             // Fall through | ||||
|         case KBC_STATE_NORMAL: | ||||
|             TRACE("  keyboard command\n"); | ||||
|             // Keyboard commands clear output buffer | ||||
|             kbc_clear_output(kbc); | ||||
|             switch (data) { | ||||
|                 case 0xED: | ||||
|                     TRACE("    set leds\n"); | ||||
|                     state = KBC_STATE_KEYBOARD; | ||||
|                     state_data = 0xFA; | ||||
|                     state_next = KBC_STATE_SET_LEDS; | ||||
|                     break; | ||||
|                 case 0xEE: | ||||
|                     TRACE("    echo\n"); | ||||
|                     // Hey, this is easy. I like easy commands | ||||
|                     state = KBC_STATE_KEYBOARD; | ||||
|                     state_data = 0xEE; | ||||
|                     break; | ||||
|                 case 0xF0: | ||||
|                     TRACE("    get/set scancode\n"); | ||||
|                     state = KBC_STATE_KEYBOARD; | ||||
|                     state_data = 0xFA; | ||||
|                     state_next = KBC_STATE_SCANCODE; | ||||
|                     break; | ||||
|                 case 0xF2: | ||||
|                     TRACE("    identify keyboard\n"); | ||||
|                     state = KBC_STATE_KEYBOARD; | ||||
|                     state_data = 0xFA; | ||||
|                     state_next = KBC_STATE_IDENTIFY_0; | ||||
|                     break; | ||||
|                 case 0xF3: | ||||
|                     TRACE("    set typematic rate/delay\n"); | ||||
|                     state = KBC_STATE_KEYBOARD; | ||||
|                     state_data = 0xFA; | ||||
|                     state_next = KBC_STATE_TYPEMATIC; | ||||
|                     break; | ||||
|                 case 0xF4: | ||||
|                     TRACE("    enable scanning\n"); | ||||
|                     kbscan_enabled = true; | ||||
|                     state = KBC_STATE_KEYBOARD; | ||||
|                     state_data = 0xFA; | ||||
|                     break; | ||||
|                 case 0xF5: | ||||
|                     TRACE("    disable scanning\n"); | ||||
|                     kbscan_enabled = false; | ||||
|                     state = KBC_STATE_KEYBOARD; | ||||
|                     state_data = 0xFA; | ||||
|                     break; | ||||
|                 case 0xF6: | ||||
|                     TRACE("    set default parameters\n"); | ||||
|                     kbc_leds = 0; | ||||
|                     kbscan_repeat_period = 91; | ||||
|                     kbscan_repeat_delay = 500; | ||||
|                     state = KBC_STATE_KEYBOARD; | ||||
|                     state_data = 0xFA; | ||||
|                     break; | ||||
|                 case 0xFF: | ||||
|                     TRACE("    self test\n"); | ||||
|                     state = KBC_STATE_KEYBOARD; | ||||
|                     state_data = 0xFA; | ||||
|                     state_next = KBC_STATE_SELF_TEST; | ||||
|                     break; | ||||
|             } | ||||
|     case KBC_STATE_TOUCHPAD: | ||||
|         // Interrupt touchpad command | ||||
|         state = KBC_STATE_NORMAL; | ||||
|         // Fall through | ||||
|     case KBC_STATE_NORMAL: | ||||
|         TRACE("  keyboard command\n"); | ||||
|         // Keyboard commands clear output buffer | ||||
|         kbc_clear_output(kbc); | ||||
|         switch (data) { | ||||
|         case 0xED: | ||||
|             TRACE("    set leds\n"); | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             state_data = 0xFA; | ||||
|             state_next = KBC_STATE_SET_LEDS; | ||||
|             break; | ||||
|         case KBC_STATE_WRITE_CONFIG: | ||||
|             TRACE("  write configuration byte\n"); | ||||
|             state = KBC_STATE_NORMAL; | ||||
|             // Enable keyboard interrupt | ||||
|             if (data & BIT(0)) { | ||||
|                 *kbc->control |= BIT(0); | ||||
|             } else { | ||||
|                 *kbc->control &= ~BIT(0); | ||||
|             } | ||||
|             // Enable mouse interrupt | ||||
|             if (data & BIT(1)) { | ||||
|                 *kbc->control |= BIT(1); | ||||
|             } else { | ||||
|                 *kbc->control &= ~BIT(1); | ||||
|             } | ||||
|             // System flag | ||||
|             if (data & BIT(2)) { | ||||
|                 *kbc->status |= BIT(2); | ||||
|             } else { | ||||
|                 *kbc->status &= ~BIT(2); | ||||
|             } | ||||
|             kbc_first = (bool)(!(data & BIT(4))); | ||||
|             kbc_second = (bool)(!(data & BIT(5))); | ||||
|             kbc_translate = (bool)(data & BIT(6)); | ||||
|         case 0xEE: | ||||
|             TRACE("    echo\n"); | ||||
|             // Hey, this is easy. I like easy commands | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             state_data = 0xEE; | ||||
|             break; | ||||
|         case KBC_STATE_SET_LEDS: | ||||
|             TRACE("  set leds\n"); | ||||
|             kbc_leds = data; | ||||
|         case 0xF0: | ||||
|             TRACE("    get/set scancode\n"); | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             state_data = 0xFA; | ||||
|             state_next = KBC_STATE_SCANCODE; | ||||
|             break; | ||||
|         case 0xF2: | ||||
|             TRACE("    identify keyboard\n"); | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             state_data = 0xFA; | ||||
|             state_next = KBC_STATE_IDENTIFY_0; | ||||
|             break; | ||||
|         case 0xF3: | ||||
|             TRACE("    set typematic rate/delay\n"); | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             state_data = 0xFA; | ||||
|             state_next = KBC_STATE_TYPEMATIC; | ||||
|             break; | ||||
|         case 0xF4: | ||||
|             TRACE("    enable scanning\n"); | ||||
|             kbscan_enabled = true; | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             state_data = 0xFA; | ||||
|             break; | ||||
|         case KBC_STATE_SCANCODE: | ||||
|             TRACE("  get/set scancode\n"); | ||||
|             #if LEVEL >= LEVEL_TRACE | ||||
|                 switch (data) { | ||||
|                     case 0x02: | ||||
|                         TRACE("    set scancode set 2\n"); | ||||
|                         break; | ||||
|                 } | ||||
|             #endif | ||||
|         case 0xF5: | ||||
|             TRACE("    disable scanning\n"); | ||||
|             kbscan_enabled = false; | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             state_data = 0xFA; | ||||
|             break; | ||||
|         case KBC_STATE_TYPEMATIC: | ||||
|             TRACE("  set typematic rate/delay\n"); | ||||
|             { | ||||
|                 // Rate: bits 0-4 | ||||
|                 uint16_t period = kbc_typematic_period[data & 0x1F]; | ||||
|                 kbscan_repeat_period = period; | ||||
|         case 0xF6: | ||||
|             TRACE("    set default parameters\n"); | ||||
|             kbc_leds = 0; | ||||
|             kbscan_repeat_period = 91; | ||||
|             kbscan_repeat_delay = 500; | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             state_data = 0xFA; | ||||
|             break; | ||||
|         case 0xFF: | ||||
|             TRACE("    self test\n"); | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             state_data = 0xFA; | ||||
|             state_next = KBC_STATE_SELF_TEST; | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case KBC_STATE_WRITE_CONFIG: | ||||
|         TRACE("  write configuration byte\n"); | ||||
|         state = KBC_STATE_NORMAL; | ||||
|         // Enable keyboard interrupt | ||||
|         if (data & BIT(0)) { | ||||
|             *kbc->control |= BIT(0); | ||||
|         } else { | ||||
|             *kbc->control &= ~BIT(0); | ||||
|         } | ||||
|         // Enable mouse interrupt | ||||
|         if (data & BIT(1)) { | ||||
|             *kbc->control |= BIT(1); | ||||
|         } else { | ||||
|             *kbc->control &= ~BIT(1); | ||||
|         } | ||||
|         // System flag | ||||
|         if (data & BIT(2)) { | ||||
|             *kbc->status |= BIT(2); | ||||
|         } else { | ||||
|             *kbc->status &= ~BIT(2); | ||||
|         } | ||||
|         kbc_first = (bool)(!(data & BIT(4))); | ||||
|         kbc_second = (bool)(!(data & BIT(5))); | ||||
|         kbc_translate = (bool)(data & BIT(6)); | ||||
|         break; | ||||
|     case KBC_STATE_SET_LEDS: | ||||
|         TRACE("  set leds\n"); | ||||
|         kbc_leds = data; | ||||
|         state = KBC_STATE_KEYBOARD; | ||||
|         state_data = 0xFA; | ||||
|         break; | ||||
|     case KBC_STATE_SCANCODE: | ||||
|         TRACE("  get/set scancode\n"); | ||||
| #if LEVEL >= LEVEL_TRACE | ||||
|         switch (data) { | ||||
|         case 0x02: | ||||
|             TRACE("    set scancode set 2\n"); | ||||
|             break; | ||||
|         } | ||||
| #endif | ||||
|         state = KBC_STATE_KEYBOARD; | ||||
|         state_data = 0xFA; | ||||
|         break; | ||||
|     case KBC_STATE_TYPEMATIC: | ||||
|         TRACE("  set typematic rate/delay\n"); | ||||
|         { | ||||
|             // Rate: bits 0-4 | ||||
|             uint16_t period = kbc_typematic_period[data & 0x1F]; | ||||
|             kbscan_repeat_period = period; | ||||
|  | ||||
|                 // Delay: bits 5-6 | ||||
|                 static const uint16_t delay[4] = {250, 500, 750, 1000}; | ||||
|                 uint8_t idx = (data & 0x60) >> 5; | ||||
|                 kbscan_repeat_delay = delay[idx]; | ||||
|             } | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             state_data = 0xFA; | ||||
|             break; | ||||
|         case KBC_STATE_WRITE_PORT: | ||||
|             TRACE("  write port byte\n"); | ||||
|             state = KBC_STATE_NORMAL; | ||||
|             break; | ||||
|         case KBC_STATE_FIRST_PORT_OUTPUT: | ||||
|             TRACE("  write first port output\n"); | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             state_data = data; | ||||
|             break; | ||||
|         case KBC_STATE_SECOND_PORT_OUTPUT: | ||||
|             TRACE("  write second port output\n"); | ||||
|             state = KBC_STATE_MOUSE; | ||||
|             state_data = data; | ||||
|             break; | ||||
|         case KBC_STATE_SECOND_PORT_INPUT: | ||||
|             TRACE("  write second port input\n"); | ||||
|             state = KBC_STATE_NORMAL; | ||||
|             // Begin write | ||||
|             *(PS2_TOUCHPAD.control) = 0x0D; | ||||
|             *(PS2_TOUCHPAD.data) = data; | ||||
|             // Pull data line low | ||||
|             *(PS2_TOUCHPAD.control) = 0x0C; | ||||
|             // Pull clock line high | ||||
|             *(PS2_TOUCHPAD.control) = 0x0E; | ||||
|             // Set wait timeout of 100 cycles | ||||
|             kbc_second_wait = 100; | ||||
|             break; | ||||
|             // Delay: bits 5-6 | ||||
|             static const uint16_t delay[4] = { 250, 500, 750, 1000 }; | ||||
|             uint8_t idx = (data & 0x60) >> 5; | ||||
|             kbscan_repeat_delay = delay[idx]; | ||||
|         } | ||||
|         state = KBC_STATE_KEYBOARD; | ||||
|         state_data = 0xFA; | ||||
|         break; | ||||
|     case KBC_STATE_WRITE_PORT: | ||||
|         TRACE("  write port byte\n"); | ||||
|         state = KBC_STATE_NORMAL; | ||||
|         break; | ||||
|     case KBC_STATE_FIRST_PORT_OUTPUT: | ||||
|         TRACE("  write first port output\n"); | ||||
|         state = KBC_STATE_KEYBOARD; | ||||
|         state_data = data; | ||||
|         break; | ||||
|     case KBC_STATE_SECOND_PORT_OUTPUT: | ||||
|         TRACE("  write second port output\n"); | ||||
|         state = KBC_STATE_MOUSE; | ||||
|         state_data = data; | ||||
|         break; | ||||
|     case KBC_STATE_SECOND_PORT_INPUT: | ||||
|         TRACE("  write second port input\n"); | ||||
|         state = KBC_STATE_NORMAL; | ||||
|         // Begin write | ||||
|         *(PS2_TOUCHPAD.control) = 0x0D; | ||||
|         *(PS2_TOUCHPAD.data) = data; | ||||
|         // Pull data line low | ||||
|         *(PS2_TOUCHPAD.control) = 0x0C; | ||||
|         // Pull clock line high | ||||
|         *(PS2_TOUCHPAD.control) = 0x0E; | ||||
|         // Set wait timeout of 100 cycles | ||||
|         kbc_second_wait = 100; | ||||
|         break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void kbc_on_output_empty(struct Kbc * kbc) { | ||||
| static void kbc_on_output_empty(struct Kbc *kbc) { | ||||
|     switch (state) { | ||||
|         case KBC_STATE_KEYBOARD: | ||||
|             TRACE("kbc keyboard: %02X\n", state_data); | ||||
|             if (kbc_keyboard(kbc, state_data, KBC_TIMEOUT)) { | ||||
|                 state = state_next; | ||||
|                 state_next = KBC_STATE_NORMAL; | ||||
|             } | ||||
|             break; | ||||
|         case KBC_STATE_TOUCHPAD: | ||||
|             state_data = *(PS2_TOUCHPAD.data); | ||||
|             // Fall through | ||||
|         case KBC_STATE_MOUSE: | ||||
|             TRACE("kbc mouse: %02X\n", state_data); | ||||
|             if (kbc_mouse(kbc, state_data, KBC_TIMEOUT)) { | ||||
|                 state = state_next; | ||||
|                 state_next = KBC_STATE_NORMAL; | ||||
|             } | ||||
|             break; | ||||
|     case KBC_STATE_KEYBOARD: | ||||
|         TRACE("kbc keyboard: %02X\n", state_data); | ||||
|         if (kbc_keyboard(kbc, state_data, KBC_TIMEOUT)) { | ||||
|             state = state_next; | ||||
|             state_next = KBC_STATE_NORMAL; | ||||
|         } | ||||
|         break; | ||||
|     case KBC_STATE_TOUCHPAD: | ||||
|         state_data = *(PS2_TOUCHPAD.data); | ||||
|         // Fall through | ||||
|     case KBC_STATE_MOUSE: | ||||
|         TRACE("kbc mouse: %02X\n", state_data); | ||||
|         if (kbc_mouse(kbc, state_data, KBC_TIMEOUT)) { | ||||
|             state = state_next; | ||||
|             state_next = KBC_STATE_NORMAL; | ||||
|         } | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     switch (state) { | ||||
|         case KBC_STATE_IDENTIFY_0: | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             state_data = 0xAB; | ||||
|             state_next = KBC_STATE_IDENTIFY_1; | ||||
|             break; | ||||
|         case KBC_STATE_IDENTIFY_1: | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             state_data = 0x83; | ||||
|             break; | ||||
|         case KBC_STATE_SELF_TEST: | ||||
|             // Yep, everything is still good, I promise | ||||
|             state = KBC_STATE_KEYBOARD; | ||||
|             state_data = 0xAA; | ||||
|             break; | ||||
|     case KBC_STATE_IDENTIFY_0: | ||||
|         state = KBC_STATE_KEYBOARD; | ||||
|         state_data = 0xAB; | ||||
|         state_next = KBC_STATE_IDENTIFY_1; | ||||
|         break; | ||||
|     case KBC_STATE_IDENTIFY_1: | ||||
|         state = KBC_STATE_KEYBOARD; | ||||
|         state_data = 0x83; | ||||
|         break; | ||||
|     case KBC_STATE_SELF_TEST: | ||||
|         // Yep, everything is still good, I promise | ||||
|         state = KBC_STATE_KEYBOARD; | ||||
|         state_data = 0xAA; | ||||
|         break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void kbc_event(struct Kbc * kbc) { | ||||
| void kbc_event(struct Kbc *kbc) { | ||||
|     uint8_t sts; | ||||
|  | ||||
|     // Read from scancode buffer when possible | ||||
|   | ||||
| @@ -28,12 +28,27 @@ void kbled_reset(void) { | ||||
| } | ||||
|  | ||||
| // Keep the following functions for compatibility - they are set via USB HID | ||||
| uint8_t kbled_get(void) { /*Always off*/ return 0; } | ||||
| uint8_t kbled_get(void) { | ||||
|     /* Always off */ | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| uint8_t kbled_max(void) { /*Always off*/ return 0; } | ||||
| uint8_t kbled_max(void) { | ||||
|     /* Always off */ | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| void kbled_set(uint8_t level) { /*Fix unused variable*/ level = level; } | ||||
| void kbled_set(uint8_t level) { | ||||
|     /* Fix unused variable */ | ||||
|     level = level; | ||||
| } | ||||
|  | ||||
| uint32_t kbled_get_color(void) { /*Always black*/ return 0; } | ||||
| uint32_t kbled_get_color(void) { | ||||
|     /* Always black */ | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| void kbled_set_color(uint32_t color) { /*Fix unused variable*/ color = color; } | ||||
| void kbled_set_color(uint32_t color) { | ||||
|     /* Fix unused variable */ | ||||
|     color = color; | ||||
| } | ||||
|   | ||||
| @@ -6,12 +6,27 @@ void kbled_init(void) {} | ||||
|  | ||||
| void kbled_reset(void) {} | ||||
|  | ||||
| uint8_t kbled_get(void) { /*Always off*/ return 0; } | ||||
| uint8_t kbled_get(void) { | ||||
|     /* Always off */ | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| uint8_t kbled_max(void) { /*Always off*/ return 0; } | ||||
| uint8_t kbled_max(void) { | ||||
|     /* Always off */ | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| void kbled_set(uint8_t level) { /*Fix unused variable*/ level = level; } | ||||
| void kbled_set(uint8_t level) { | ||||
|     /* Fix unused variable */ | ||||
|     level = level; | ||||
| } | ||||
|  | ||||
| uint32_t kbled_get_color(void) { /*Always black*/ return 0; } | ||||
| uint32_t kbled_get_color(void) { | ||||
|     /* Always black */ | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| void kbled_set_color(uint32_t color) { /*Fix unused variable*/ color = color; } | ||||
| void kbled_set_color(uint32_t color) { | ||||
|     /* Fix unused variable */ | ||||
|     color = color; | ||||
| } | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| #include <ec/dac.h> | ||||
|  | ||||
| #if !defined(KBLED_DAC) | ||||
|     #error "KBLED_DAC must be defined" | ||||
| #error "KBLED_DAC must be defined" | ||||
| #endif | ||||
|  | ||||
| #define KBLED_DACDAT xconcat(DACDAT, KBLED_DAC) | ||||
| @@ -54,6 +54,12 @@ void kbled_set(uint8_t level) { | ||||
|     KBLED_DACDAT = raw; | ||||
| } | ||||
|  | ||||
| uint32_t kbled_get_color(void) { /* Always white */ return 0xFFFFFF; } | ||||
| uint32_t kbled_get_color(void) { | ||||
|     /* Always white */ | ||||
|     return 0xFFFFFF; | ||||
| } | ||||
|  | ||||
| void kbled_set_color(uint32_t color) { /*Fix unused variable*/ color = color; } | ||||
| void kbled_set_color(uint32_t color) { | ||||
|     /* Fix unused variable */ | ||||
|     color = color; | ||||
| } | ||||
|   | ||||
| @@ -165,125 +165,129 @@ static bool kbscan_has_ghost_in_row(uint8_t row, uint8_t rowdata) { | ||||
|  | ||||
| static void hardware_hotkey(uint16_t key) { | ||||
|     switch (key) { | ||||
|         case K_DISPLAY_TOGGLE: | ||||
|             gpio_set(&BKL_EN, !gpio_get(&BKL_EN)); | ||||
|             break; | ||||
|         case K_CAMERA_TOGGLE: | ||||
|             gpio_set(&CCD_EN, !gpio_get(&CCD_EN)); | ||||
|             break; | ||||
|         case K_FAN_TOGGLE: | ||||
|             fan_max = !fan_max; | ||||
|             break; | ||||
|         case K_KBD_BKL: | ||||
|             kbled_set(kbled_get() + 1); | ||||
|             break; | ||||
|         case K_KBD_COLOR: | ||||
|             if (acpi_ecos != EC_OS_FULL) kbled_hotkey_color(); | ||||
|             break; | ||||
|         case K_KBD_DOWN: | ||||
|             if (acpi_ecos != EC_OS_FULL) kbled_hotkey_down(); | ||||
|             break; | ||||
|         case K_KBD_UP: | ||||
|             if (acpi_ecos != EC_OS_FULL) kbled_hotkey_up(); | ||||
|             break; | ||||
|         case K_KBD_TOGGLE: | ||||
|             if (acpi_ecos != EC_OS_FULL) kbled_hotkey_toggle(); | ||||
|             break; | ||||
|     case K_DISPLAY_TOGGLE: | ||||
|         gpio_set(&BKL_EN, !gpio_get(&BKL_EN)); | ||||
|         break; | ||||
|     case K_CAMERA_TOGGLE: | ||||
|         gpio_set(&CCD_EN, !gpio_get(&CCD_EN)); | ||||
|         break; | ||||
|     case K_FAN_TOGGLE: | ||||
|         fan_max = !fan_max; | ||||
|         break; | ||||
|     case K_KBD_BKL: | ||||
|         kbled_set(kbled_get() + 1); | ||||
|         break; | ||||
|     case K_KBD_COLOR: | ||||
|         if (acpi_ecos != EC_OS_FULL) | ||||
|             kbled_hotkey_color(); | ||||
|         break; | ||||
|     case K_KBD_DOWN: | ||||
|         if (acpi_ecos != EC_OS_FULL) | ||||
|             kbled_hotkey_down(); | ||||
|         break; | ||||
|     case K_KBD_UP: | ||||
|         if (acpi_ecos != EC_OS_FULL) | ||||
|             kbled_hotkey_up(); | ||||
|         break; | ||||
|     case K_KBD_TOGGLE: | ||||
|         if (acpi_ecos != EC_OS_FULL) | ||||
|             kbled_hotkey_toggle(); | ||||
|         break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| bool kbscan_press(uint16_t key, bool pressed, uint8_t * layer) { | ||||
| bool kbscan_press(uint16_t key, bool pressed, uint8_t *layer) { | ||||
|     // Wake from sleep on keypress | ||||
|     if (pressed && | ||||
|         lid_state && | ||||
|         (power_state == POWER_STATE_S3)) { | ||||
|     if (pressed && lid_state && (power_state == POWER_STATE_S3)) { | ||||
|         pmc_swi(); | ||||
|     } | ||||
|  | ||||
|     switch (key & KT_MASK) { | ||||
|         case (KT_NORMAL): | ||||
|     case (KT_NORMAL): | ||||
|         if (kbscan_enabled) { | ||||
|             kbc_scancode(key, pressed); | ||||
|         } | ||||
|         break; | ||||
|     case (KT_FN): | ||||
|         if (layer != NULL) { | ||||
|             if (pressed) | ||||
|                 *layer = 1; | ||||
|             else | ||||
|                 *layer = 0; | ||||
|         } else { | ||||
|             // In the case no layer can be set, reset bit | ||||
|             return false; | ||||
|         } | ||||
|         break; | ||||
|     case (KT_COMBO): | ||||
|         switch (key & 0xFF) { | ||||
|         case COMBO_DISPLAY_MODE: | ||||
|             if (kbscan_enabled) { | ||||
|                 kbc_scancode(key, pressed); | ||||
|             } | ||||
|             break; | ||||
|         case (KT_FN): | ||||
|             if (layer != NULL) { | ||||
|                 if (pressed) *layer = 1; | ||||
|                 else *layer = 0; | ||||
|             } else { | ||||
|                 // In the case no layer can be set, reset bit | ||||
|                 return false; | ||||
|             } | ||||
|             break; | ||||
|         case (KT_COMBO): | ||||
|             switch (key & 0xFF) { | ||||
|                 case COMBO_DISPLAY_MODE: | ||||
|                     if (kbscan_enabled) { | ||||
|                         if (pressed) { | ||||
|                             kbc_scancode(K_LEFT_SUPER, true); | ||||
|                             kbc_scancode(K_P, true); | ||||
|                             kbc_scancode(K_P, false); | ||||
|                         } else { | ||||
|                             kbc_scancode(K_LEFT_SUPER, false); | ||||
|                         } | ||||
|                     } | ||||
|                     break; | ||||
|                 case COMBO_PRINT_SCREEN: | ||||
|                     if (kbscan_enabled) { | ||||
|                         if (pressed) { | ||||
|                             kbc_scancode(KF_E0 | 0x12, true); | ||||
|                             kbc_scancode(KF_E0 | 0x7C, true); | ||||
|                         } else { | ||||
|                             kbc_scancode(KF_E0 | 0x7C, false); | ||||
|                             kbc_scancode(KF_E0 | 0x12, false); | ||||
|                         } | ||||
|                     } | ||||
|                     break; | ||||
|                 case COMBO_PAUSE: | ||||
|                     if (kbscan_enabled) { | ||||
|                         if (pressed) { | ||||
|                             kbc_scancode(0xE1, true); | ||||
|                             kbc_scancode(0x14, true); | ||||
|                             kbc_scancode(0x77, true); | ||||
|                             kbc_scancode(0xE1, true); | ||||
|                             kbc_scancode(0x14, false); | ||||
|                             kbc_scancode(0x77, false); | ||||
|                         } | ||||
|                     } | ||||
|                     break; | ||||
|             } | ||||
|             break; | ||||
|         case (KT_SCI): | ||||
|             if (pressed) { | ||||
|                 // Send SCI if ACPI OS is loaded | ||||
|                 if (acpi_ecos != EC_OS_NONE) { | ||||
|                     uint8_t sci = (uint8_t)(key & 0xFF); | ||||
|                     if (!pmc_sci(&PMC_1, sci)) { | ||||
|                         // In the case of ignored SCI, reset bit | ||||
|                         return false; | ||||
|                     } | ||||
|                 if (pressed) { | ||||
|                     kbc_scancode(K_LEFT_SUPER, true); | ||||
|                     kbc_scancode(K_P, true); | ||||
|                     kbc_scancode(K_P, false); | ||||
|                 } else { | ||||
|                     kbc_scancode(K_LEFT_SUPER, false); | ||||
|                 } | ||||
|  | ||||
|                 // Handle hardware hotkeys | ||||
|                 hardware_hotkey(key); | ||||
|             } | ||||
|             break; | ||||
|         case (KT_SCI_EXTRA): | ||||
|             if (pressed) { | ||||
|                 // Send SCI if ACPI OS is loaded | ||||
|                 if (acpi_ecos != EC_OS_NONE) { | ||||
|                     uint8_t sci = SCI_EXTRA; | ||||
|                     sci_extra = (uint8_t)(key & 0xFF); | ||||
|                     if (!pmc_sci(&PMC_1, sci)) { | ||||
|                         // In the case of ignored SCI, reset bit | ||||
|                         return false; | ||||
|                     } | ||||
|         case COMBO_PRINT_SCREEN: | ||||
|             if (kbscan_enabled) { | ||||
|                 if (pressed) { | ||||
|                     kbc_scancode(KF_E0 | 0x12, true); | ||||
|                     kbc_scancode(KF_E0 | 0x7C, true); | ||||
|                 } else { | ||||
|                     kbc_scancode(KF_E0 | 0x7C, false); | ||||
|                     kbc_scancode(KF_E0 | 0x12, false); | ||||
|                 } | ||||
|  | ||||
|                 // Handle hardware hotkeys | ||||
|                 hardware_hotkey(key); | ||||
|             } | ||||
|             break; | ||||
|         case COMBO_PAUSE: | ||||
|             if (kbscan_enabled) { | ||||
|                 if (pressed) { | ||||
|                     kbc_scancode(0xE1, true); | ||||
|                     kbc_scancode(0x14, true); | ||||
|                     kbc_scancode(0x77, true); | ||||
|                     kbc_scancode(0xE1, true); | ||||
|                     kbc_scancode(0x14, false); | ||||
|                     kbc_scancode(0x77, false); | ||||
|                 } | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case (KT_SCI): | ||||
|         if (pressed) { | ||||
|             // Send SCI if ACPI OS is loaded | ||||
|             if (acpi_ecos != EC_OS_NONE) { | ||||
|                 uint8_t sci = (uint8_t)(key & 0xFF); | ||||
|                 if (!pmc_sci(&PMC_1, sci)) { | ||||
|                     // In the case of ignored SCI, reset bit | ||||
|                     return false; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Handle hardware hotkeys | ||||
|             hardware_hotkey(key); | ||||
|         } | ||||
|         break; | ||||
|     case (KT_SCI_EXTRA): | ||||
|         if (pressed) { | ||||
|             // Send SCI if ACPI OS is loaded | ||||
|             if (acpi_ecos != EC_OS_NONE) { | ||||
|                 uint8_t sci = SCI_EXTRA; | ||||
|                 sci_extra = (uint8_t)(key & 0xFF); | ||||
|                 if (!pmc_sci(&PMC_1, sci)) { | ||||
|                     // In the case of ignored SCI, reset bit | ||||
|                     return false; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Handle hardware hotkeys | ||||
|             hardware_hotkey(key); | ||||
|         } | ||||
|         break; | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
| @@ -344,8 +348,10 @@ void kbscan_event(void) { | ||||
|  | ||||
|             // A key was pressed or released | ||||
|             for (uint8_t j = 0; j < KM_IN; j++) { | ||||
|                 // clang-format off | ||||
|                 bool new_b = new & BIT(j); | ||||
|                 bool last_b = last & BIT(j); | ||||
|                 // clang-format on | ||||
|                 if (new_b != last_b) { | ||||
|                     bool reset = false; | ||||
|  | ||||
| @@ -374,7 +380,7 @@ void kbscan_event(void) { | ||||
|                         keymap_get(key_layer, i, j, &key); | ||||
|                         if (key) { | ||||
|                             DEBUG("KB %d, %d, %d = 0x%04X, %d\n", i, j, key_layer, key, new_b); | ||||
|                             if(!kbscan_press(key, new_b, &layer)){ | ||||
|                             if (!kbscan_press(key, new_b, &layer)) { | ||||
|                                 // In the case of ignored key press/release, reset bit | ||||
|                                 reset = true; | ||||
|                             } | ||||
| @@ -406,7 +412,7 @@ void kbscan_event(void) { | ||||
|             } | ||||
|  | ||||
|             kbscan_matrix[i] = new; | ||||
|         } else if (new && repeat_key != 0 && key_should_repeat(repeat_key)) { | ||||
|         } else if (new &&repeat_key != 0 && key_should_repeat(repeat_key)) { | ||||
|             // A key is being pressed | ||||
|             uint32_t time = time_get(); | ||||
|             static uint32_t repeat_start = 0; | ||||
|   | ||||
| @@ -36,19 +36,29 @@ bool keymap_erase_config(void) { | ||||
|  | ||||
| bool keymap_load_config(void) { | ||||
|     // Check signature | ||||
|     if (flash_read_u16(CONFIG_ADDR) != CONFIG_SIGNATURE) return false; | ||||
|     if (flash_read_u16(CONFIG_ADDR) != CONFIG_SIGNATURE) | ||||
|         return false; | ||||
|  | ||||
|     // Read the keymap if signature is valid | ||||
|     flash_read(CONFIG_ADDR + sizeof(CONFIG_SIGNATURE), (uint8_t *)DYNAMIC_KEYMAP, sizeof(DYNAMIC_KEYMAP)); | ||||
|     flash_read( | ||||
|         CONFIG_ADDR + sizeof(CONFIG_SIGNATURE), | ||||
|         (uint8_t *)DYNAMIC_KEYMAP, | ||||
|         sizeof(DYNAMIC_KEYMAP) | ||||
|     ); | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| bool keymap_save_config(void) { | ||||
|     // Erase config region | ||||
|     if (!keymap_erase_config()) return false; | ||||
|     if (!keymap_erase_config()) | ||||
|         return false; | ||||
|  | ||||
|     // Write the keymap | ||||
|     flash_write(CONFIG_ADDR + sizeof(CONFIG_SIGNATURE), (uint8_t *)DYNAMIC_KEYMAP, sizeof(DYNAMIC_KEYMAP)); | ||||
|     flash_write( | ||||
|         CONFIG_ADDR + sizeof(CONFIG_SIGNATURE), | ||||
|         (uint8_t *)DYNAMIC_KEYMAP, | ||||
|         sizeof(DYNAMIC_KEYMAP) | ||||
|     ); | ||||
|  | ||||
|     // Write the length of the keymap, as a signature | ||||
|     flash_write_u16(CONFIG_ADDR, CONFIG_SIGNATURE); | ||||
| @@ -57,7 +67,7 @@ bool keymap_save_config(void) { | ||||
|     return flash_read_u16(CONFIG_ADDR) == CONFIG_SIGNATURE; | ||||
| } | ||||
|  | ||||
| bool keymap_get(uint8_t layer, uint8_t output, uint8_t input, uint16_t * value) { | ||||
| bool keymap_get(uint8_t layer, uint8_t output, uint8_t input, uint16_t *value) { | ||||
|     if (layer < KM_LAY && output < KM_OUT && input < KM_IN) { | ||||
|         *value = DYNAMIC_KEYMAP[layer][output][input]; | ||||
|         return true; | ||||
|   | ||||
| @@ -31,7 +31,7 @@ | ||||
| #include <ec/ec.h> | ||||
|  | ||||
| #ifdef PARALLEL_DEBUG | ||||
|     #include <board/parallel.h> | ||||
| #include <board/parallel.h> | ||||
| #endif // PARALLEL_DEBUG | ||||
|  | ||||
| void external_0(void) __interrupt(0) {} | ||||
| @@ -99,25 +99,25 @@ void main(void) { | ||||
|     uint32_t last_time_battery = 0; | ||||
|     uint32_t last_time_fan = 0; | ||||
|  | ||||
|     for(main_cycle = 0; ; main_cycle++) { | ||||
|     for (main_cycle = 0;; main_cycle++) { | ||||
|         switch (main_cycle % 3U) { | ||||
|             case 0: | ||||
|                 // Handle power states | ||||
|                 power_event(); | ||||
|                 break; | ||||
|             case 1: | ||||
|         case 0: | ||||
|             // Handle power states | ||||
|             power_event(); | ||||
|             break; | ||||
|         case 1: | ||||
| #if PARALLEL_DEBUG | ||||
|                 if (!parallel_debug) | ||||
|             if (!parallel_debug) | ||||
| #endif // PARALLEL_DEBUG | ||||
|                 { | ||||
|                     // Scans keyboard and sends keyboard packets | ||||
|                     kbscan_event(); | ||||
|                 } | ||||
|                 break; | ||||
|             case 2: | ||||
|                 // Handle lid close/open | ||||
|                 lid_event(); | ||||
|                 break; | ||||
|             { | ||||
|                 // Scans keyboard and sends keyboard packets | ||||
|                 kbscan_event(); | ||||
|             } | ||||
|             break; | ||||
|         case 2: | ||||
|             // Handle lid close/open | ||||
|             lid_event(); | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         if (main_cycle == 0) { | ||||
|   | ||||
| @@ -19,12 +19,14 @@ | ||||
|  * nWAIT    = KSOH[1] | ||||
|  */ | ||||
|  | ||||
| // clang-format off | ||||
| #define CTL_WRITE   BIT(0) | ||||
| #define CTL_DATA    BIT(1) | ||||
| #define CTL_RESET   BIT(2) | ||||
| #define CTL_ADDR    BIT(3) | ||||
|  | ||||
| #define STS_WAIT    BIT(1) | ||||
| // clang-format on | ||||
|  | ||||
| // Maximum peripheral response time in ms | ||||
| #define PARALLEL_TIMEOUT 10 | ||||
| @@ -82,7 +84,7 @@ bool parallel_init(void) { | ||||
|     return parallel_wait_peripheral(STS_WAIT, 0); | ||||
| } | ||||
|  | ||||
| int16_t parallel_write(uint8_t * data, uint16_t length) { | ||||
| int16_t parallel_write(uint8_t *data, uint16_t length) { | ||||
|     // Assert nWRITE | ||||
|     KSIGDAT &= ~CTL_WRITE; | ||||
|  | ||||
|   | ||||
| @@ -11,19 +11,19 @@ | ||||
| #include <ec/pwm.h> | ||||
|  | ||||
| #ifndef USE_S0IX | ||||
|     #define USE_S0IX 0 | ||||
| #define USE_S0IX 0 | ||||
| #endif | ||||
|  | ||||
| // Fan speed is the lowest requested over HEATUP seconds | ||||
| #ifndef BOARD_HEATUP | ||||
|     #define BOARD_HEATUP 4 | ||||
| #define BOARD_HEATUP 4 | ||||
| #endif | ||||
|  | ||||
| static uint8_t FAN_HEATUP[BOARD_HEATUP] = { 0 }; | ||||
|  | ||||
| // Fan speed is the highest HEATUP speed over COOLDOWN seconds | ||||
| #ifndef BOARD_COOLDOWN | ||||
|     #define BOARD_COOLDOWN 10 | ||||
| #define BOARD_COOLDOWN 10 | ||||
| #endif | ||||
|  | ||||
| static uint8_t FAN_COOLDOWN[BOARD_COOLDOWN] = { 0 }; | ||||
| @@ -36,7 +36,9 @@ int16_t peci_temp = 0; | ||||
|  | ||||
| #define PECI_TEMP(X) ((int16_t)(X)) | ||||
|  | ||||
| // clang-format off | ||||
| #define FAN_POINT(T, D) { .temp = PECI_TEMP(T), .duty = PWM_DUTY(D) } | ||||
| // clang-format on | ||||
|  | ||||
| // Fan curve with temperature in degrees C, duty cycle in percent | ||||
| static struct FanPoint __code FAN_POINTS[] = { | ||||
|   | ||||
| @@ -60,7 +60,7 @@ static void pmc_sci_interrupt(void) { | ||||
| #endif // CONFIG_BUS_ESPI | ||||
| } | ||||
|  | ||||
| bool pmc_sci(struct Pmc * pmc, uint8_t sci) { | ||||
| bool pmc_sci(struct Pmc *pmc, uint8_t sci) { | ||||
|     // Set SCI pending bit | ||||
|     pmc_set_status(pmc, pmc_status(pmc) | BIT(5)); | ||||
|  | ||||
| @@ -107,7 +107,7 @@ void pmc_swi(void) { | ||||
| static enum PmcState state = PMC_STATE_DEFAULT; | ||||
| static uint8_t state_data = 0; | ||||
|  | ||||
| static void pmc_on_input_command(struct Pmc * pmc, uint8_t data) { | ||||
| static void pmc_on_input_command(struct Pmc *pmc, uint8_t data) { | ||||
|     TRACE("pmc cmd: %02X\n", data); | ||||
|     state = PMC_STATE_DEFAULT; | ||||
|     switch (data) { | ||||
| @@ -175,15 +175,15 @@ static void pmc_on_input_data(uint8_t data) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void pmc_on_output_empty(struct Pmc * pmc) { | ||||
| static void pmc_on_output_empty(struct Pmc *pmc) { | ||||
|     switch (state) { | ||||
|         case PMC_STATE_WRITE: | ||||
|             TRACE("pmc write: %02X\n", state_data); | ||||
|             state = PMC_STATE_DEFAULT; | ||||
|             pmc_write(pmc, state_data); | ||||
|             // Send SCI for OBF=1 | ||||
|             pmc_sci_interrupt(); | ||||
|             break; | ||||
|     case PMC_STATE_WRITE: | ||||
|         TRACE("pmc write: %02X\n", state_data); | ||||
|         state = PMC_STATE_DEFAULT; | ||||
|         pmc_write(pmc, state_data); | ||||
|         // Send SCI for OBF=1 | ||||
|         pmc_sci_interrupt(); | ||||
|         break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -213,7 +213,7 @@ static void pmc_hack(void) { | ||||
| static void pmc_hack(void) {} | ||||
| #endif | ||||
|  | ||||
| void pmc_event(struct Pmc * pmc) { | ||||
| void pmc_event(struct Pmc *pmc) { | ||||
|     uint8_t sts; | ||||
|  | ||||
|     pmc_hack(); | ||||
|   | ||||
| @@ -18,73 +18,74 @@ | ||||
| #include <common/debug.h> | ||||
|  | ||||
| #if CONFIG_BUS_ESPI | ||||
|     #include <ec/espi.h> | ||||
|     #include <board/espi.h> | ||||
| #include <ec/espi.h> | ||||
| #include <board/espi.h> | ||||
| #endif | ||||
|  | ||||
| #ifndef USE_S0IX | ||||
|     #define USE_S0IX 0 | ||||
| #define USE_S0IX 0 | ||||
| #endif | ||||
|  | ||||
| #define GPIO_SET_DEBUG(G, V) { \ | ||||
|     DEBUG("%s = %s\n", #G, V ? "true" : "false"); \ | ||||
|     gpio_set(&G, V); \ | ||||
| } | ||||
| #define GPIO_SET_DEBUG(G, V) \ | ||||
|     { \ | ||||
|         DEBUG("%s = %s\n", #G, V ? "true" : "false"); \ | ||||
|         gpio_set(&G, V); \ | ||||
|     } | ||||
|  | ||||
| #ifndef HAVE_EC_EN | ||||
|     #define HAVE_EC_EN 1 | ||||
| #define HAVE_EC_EN 1 | ||||
| #endif | ||||
|  | ||||
| #ifndef HAVE_LAN_WAKEUP_N | ||||
|     #define HAVE_LAN_WAKEUP_N 1 | ||||
| #define HAVE_LAN_WAKEUP_N 1 | ||||
| #endif | ||||
|  | ||||
| #ifndef HAVE_LED_BAT_CHG | ||||
|     #define HAVE_LED_BAT_CHG 1 | ||||
| #define HAVE_LED_BAT_CHG 1 | ||||
| #endif | ||||
|  | ||||
| #ifndef HAVE_LED_BAT_FULL | ||||
|     #define HAVE_LED_BAT_FULL 1 | ||||
| #define HAVE_LED_BAT_FULL 1 | ||||
| #endif | ||||
|  | ||||
| #ifndef HAVE_PCH_DPWROK_EC | ||||
|     #define HAVE_PCH_DPWROK_EC 1 | ||||
| #define HAVE_PCH_DPWROK_EC 1 | ||||
| #endif | ||||
|  | ||||
| #ifndef HAVE_PCH_PWROK_EC | ||||
|     #define HAVE_PCH_PWROK_EC 1 | ||||
| #define HAVE_PCH_PWROK_EC 1 | ||||
| #endif | ||||
|  | ||||
| #ifndef HAVE_PM_PWROK | ||||
|     #define HAVE_PM_PWROK 1 | ||||
| #define HAVE_PM_PWROK 1 | ||||
| #endif | ||||
|  | ||||
| #ifndef HAVE_SLP_SUS_N | ||||
|     #define HAVE_SLP_SUS_N 1 | ||||
| #define HAVE_SLP_SUS_N 1 | ||||
| #endif | ||||
|  | ||||
| #ifndef HAVE_XLP_OUT | ||||
|     #define HAVE_XLP_OUT 1 | ||||
| #define HAVE_XLP_OUT 1 | ||||
| #endif | ||||
| #ifndef HAVE_SUSWARN_N | ||||
|     #define HAVE_SUSWARN_N 1 | ||||
| #define HAVE_SUSWARN_N 1 | ||||
| #endif | ||||
|  | ||||
| #ifndef HAVE_SUS_PWR_ACK | ||||
|     #define HAVE_SUS_PWR_ACK 1 | ||||
| #define HAVE_SUS_PWR_ACK 1 | ||||
| #endif | ||||
|  | ||||
| #ifndef HAVE_VA_EC_EN | ||||
|     #define HAVE_VA_EC_EN 1 | ||||
| #define HAVE_VA_EC_EN 1 | ||||
| #endif | ||||
|  | ||||
| // Only galp6 has this, so disable by default. | ||||
| #ifndef HAVE_PD_EN | ||||
|     #define HAVE_PD_EN 0 | ||||
| #define HAVE_PD_EN 0 | ||||
| #endif | ||||
|  | ||||
| #ifndef HAVE_XLP_OUT | ||||
|     #define HAVE_XLP_OUT 1 | ||||
| #define HAVE_XLP_OUT 1 | ||||
| #endif | ||||
|  | ||||
| extern uint8_t main_cycle; | ||||
| @@ -150,22 +151,22 @@ void update_power_state(void) { | ||||
|     if (power_state != new_power_state) { | ||||
|         power_state = new_power_state; | ||||
|  | ||||
|     #if LEVEL >= LEVEL_DEBUG | ||||
| #if LEVEL >= LEVEL_DEBUG | ||||
|         switch (power_state) { | ||||
|             case POWER_STATE_OFF: | ||||
|                 DEBUG("POWER_STATE_OFF\n"); | ||||
|                 break; | ||||
|             case POWER_STATE_S5: | ||||
|                 DEBUG("POWER_STATE_S5\n"); | ||||
|                 break; | ||||
|             case POWER_STATE_S3: | ||||
|                 DEBUG("POWER_STATE_S3\n"); | ||||
|                 break; | ||||
|             case POWER_STATE_S0: | ||||
|                 DEBUG("POWER_STATE_S0\n"); | ||||
|                 break; | ||||
|         case POWER_STATE_OFF: | ||||
|             DEBUG("POWER_STATE_OFF\n"); | ||||
|             break; | ||||
|         case POWER_STATE_S5: | ||||
|             DEBUG("POWER_STATE_S5\n"); | ||||
|             break; | ||||
|         case POWER_STATE_S3: | ||||
|             DEBUG("POWER_STATE_S3\n"); | ||||
|             break; | ||||
|         case POWER_STATE_S0: | ||||
|             DEBUG("POWER_STATE_S0\n"); | ||||
|             break; | ||||
|         } | ||||
|     #endif | ||||
| #endif | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -243,10 +244,10 @@ void power_on(void) { | ||||
|             break; | ||||
|         } | ||||
|  | ||||
| #if CONFIG_BUS_ESPI | ||||
|         // Check for VW changes | ||||
|         #if CONFIG_BUS_ESPI | ||||
|             espi_event(); | ||||
|         #endif // CONFIG_BUS_ESPI | ||||
|         espi_event(); | ||||
| #endif // CONFIG_BUS_ESPI | ||||
|  | ||||
|         // Extra wait until SUSPWRDNACK is valid | ||||
|         delay_ms(1); | ||||
| @@ -434,11 +435,11 @@ void power_event(void) { | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     #if LEVEL >= LEVEL_DEBUG | ||||
|         else if (ps_new && !ps_last) { | ||||
|             DEBUG("%02X: Power switch release\n", main_cycle); | ||||
|         } | ||||
|     #endif | ||||
| #if LEVEL >= LEVEL_DEBUG | ||||
|     else if (ps_new && !ps_last) { | ||||
|         DEBUG("%02X: Power switch release\n", main_cycle); | ||||
|     } | ||||
| #endif | ||||
|     ps_last = ps_new; | ||||
|  | ||||
|     // Send power signal to PCH | ||||
| @@ -467,7 +468,7 @@ void power_event(void) { | ||||
|         // Assert SYS_PWROK, system can finally perform PLT_RST# and boot | ||||
|         GPIO_SET_DEBUG(PCH_PWROK_EC, true); | ||||
| #endif // HAVE_PCH_PWROK_EC | ||||
|     } else if(!pg_new && pg_last) { | ||||
|     } else if (!pg_new && pg_last) { | ||||
|         DEBUG("%02X: ALL_SYS_PWRGD de-asserted\n", main_cycle); | ||||
|  | ||||
| #if HAVE_PCH_PWROK_EC | ||||
| @@ -482,14 +483,15 @@ void power_event(void) { | ||||
|     } | ||||
|     pg_last = pg_new; | ||||
|  | ||||
|     // clang-format off | ||||
|     static bool rst_last = false; | ||||
|     bool rst_new = gpio_get(&BUF_PLT_RST_N); | ||||
|     #if LEVEL >= LEVEL_DEBUG | ||||
|         if (!rst_new && rst_last) { | ||||
|             DEBUG("%02X: PLT_RST# asserted\n", main_cycle); | ||||
|         } else | ||||
|     #endif | ||||
|     if(rst_new && !rst_last) { | ||||
| #if LEVEL >= LEVEL_DEBUG | ||||
|     if (!rst_new && rst_last) { | ||||
|         DEBUG("%02X: PLT_RST# asserted\n", main_cycle); | ||||
|     } else | ||||
| #endif | ||||
|     if (rst_new && !rst_last) { | ||||
|         DEBUG("%02X: PLT_RST# de-asserted\n", main_cycle); | ||||
| #if CONFIG_BUS_ESPI | ||||
|         espi_reset(); | ||||
| @@ -498,18 +500,19 @@ void power_event(void) { | ||||
| #endif // CONFIG_BUS_ESPI | ||||
|     } | ||||
|     rst_last = rst_new; | ||||
|     // clang-format on | ||||
|  | ||||
| #if HAVE_SLP_SUS_N | ||||
|     #if LEVEL >= LEVEL_DEBUG | ||||
|         static bool sus_last = true; | ||||
|         bool sus_new = gpio_get(&SLP_SUS_N); | ||||
|         if (!sus_new && sus_last) { | ||||
|             DEBUG("%02X: SLP_SUS# asserted\n", main_cycle); | ||||
|         } else if (sus_new && !sus_last) { | ||||
|             DEBUG("%02X: SLP_SUS# de-asserted\n", main_cycle); | ||||
|         } | ||||
|         sus_last = sus_new; | ||||
|     #endif | ||||
| #if LEVEL >= LEVEL_DEBUG | ||||
|     static bool sus_last = true; | ||||
|     bool sus_new = gpio_get(&SLP_SUS_N); | ||||
|     if (!sus_new && sus_last) { | ||||
|         DEBUG("%02X: SLP_SUS# asserted\n", main_cycle); | ||||
|     } else if (sus_new && !sus_last) { | ||||
|         DEBUG("%02X: SLP_SUS# de-asserted\n", main_cycle); | ||||
|     } | ||||
|     sus_last = sus_new; | ||||
| #endif | ||||
| #endif // HAVE_SLP_SUS_N | ||||
|  | ||||
| #if CONFIG_BUS_ESPI | ||||
| @@ -519,13 +522,13 @@ void power_event(void) { | ||||
|     // state is S3 | ||||
|     static bool ack_last = false; | ||||
|     bool ack_new = gpio_get(&SUSWARN_N); | ||||
|     #if LEVEL >= LEVEL_DEBUG | ||||
|         if (ack_new && !ack_last) { | ||||
|             DEBUG("%02X: SUSPWRDNACK asserted\n", main_cycle); | ||||
|         } else if (!ack_new && ack_last) { | ||||
|             DEBUG("%02X: SUSPWRDNACK de-asserted\n", main_cycle); | ||||
|         } | ||||
|     #endif | ||||
| #if LEVEL >= LEVEL_DEBUG | ||||
|     if (ack_new && !ack_last) { | ||||
|         DEBUG("%02X: SUSPWRDNACK asserted\n", main_cycle); | ||||
|     } else if (!ack_new && ack_last) { | ||||
|         DEBUG("%02X: SUSPWRDNACK de-asserted\n", main_cycle); | ||||
|     } | ||||
| #endif | ||||
|     ack_last = ack_new; | ||||
|  | ||||
|     if (ack_new) | ||||
| @@ -547,11 +550,11 @@ void power_event(void) { | ||||
|             power_on(); | ||||
|         } | ||||
|     } | ||||
|     #if LEVEL >= LEVEL_DEBUG | ||||
|         else if (wake_new && !wake_last) { | ||||
|             DEBUG("%02X: LAN_WAKEUP# de-asserted\n", main_cycle); | ||||
|         } | ||||
|     #endif | ||||
| #if LEVEL >= LEVEL_DEBUG | ||||
|     else if (wake_new && !wake_last) { | ||||
|         DEBUG("%02X: LAN_WAKEUP# de-asserted\n", main_cycle); | ||||
|     } | ||||
| #endif | ||||
|     wake_last = wake_new; | ||||
| #endif // HAVE_LAN_WAKEUP_N | ||||
|  | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| // Include scratch ROM | ||||
| uint8_t __code __at(SCRATCH_OFFSET) scratch_rom[] = { | ||||
|     #include <scratch.h> | ||||
| #include <scratch.h> | ||||
| }; | ||||
|  | ||||
| // Enter or exit scratch ROM | ||||
|   | ||||
| @@ -22,7 +22,7 @@ void smbus_init(void) { | ||||
|     i2c_reset(&I2C_SMBUS, true); | ||||
| } | ||||
|  | ||||
| int16_t smbus_read(uint8_t address, uint8_t command, uint16_t * data) { | ||||
| int16_t smbus_read(uint8_t address, uint8_t command, uint16_t *data) { | ||||
|     return i2c_get(&I2C_SMBUS, address, command, (uint8_t *)data, 2); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -18,9 +18,9 @@ | ||||
| #include <string.h> | ||||
|  | ||||
| #ifndef __SCRATCH__ | ||||
|     #include <board/scratch.h> | ||||
|     #include <board/kbled.h> | ||||
|     #include <board/kbscan.h> | ||||
| #include <board/scratch.h> | ||||
| #include <board/kbled.h> | ||||
| #include <board/kbscan.h> | ||||
| #endif | ||||
| #include <board/smfi.h> | ||||
| #include <common/command.h> | ||||
| @@ -118,15 +118,15 @@ static enum Result cmd_print(void) { | ||||
|  | ||||
| static enum Result cmd_fan_get(void) { | ||||
|     switch (smfi_cmd[SMFI_CMD_DATA]) { | ||||
|         case 0: | ||||
|             // Get duty of fan 0 | ||||
|             smfi_cmd[SMFI_CMD_DATA + 1] = DCR2; | ||||
|             return RES_OK; | ||||
|         case 1: | ||||
|             // Get duty of fan 1 | ||||
|             //TODO: only allow on platforms like addw2 | ||||
|             smfi_cmd[SMFI_CMD_DATA + 1] = DCR4; | ||||
|             return RES_OK; | ||||
|     case 0: | ||||
|         // Get duty of fan 0 | ||||
|         smfi_cmd[SMFI_CMD_DATA + 1] = DCR2; | ||||
|         return RES_OK; | ||||
|     case 1: | ||||
|         // Get duty of fan 1 | ||||
|         //TODO: only allow on platforms like addw2 | ||||
|         smfi_cmd[SMFI_CMD_DATA + 1] = DCR4; | ||||
|         return RES_OK; | ||||
|     } | ||||
|  | ||||
|     // Failed if fan not found | ||||
| @@ -135,15 +135,15 @@ static enum Result cmd_fan_get(void) { | ||||
|  | ||||
| static enum Result cmd_fan_set(void) { | ||||
|     switch (smfi_cmd[SMFI_CMD_DATA]) { | ||||
|         case 0: | ||||
|             // Set duty cycle of fan 0 | ||||
|             DCR2 = smfi_cmd[SMFI_CMD_DATA + 1]; | ||||
|             return RES_OK; | ||||
|         case 1: | ||||
|             // Set duty cycle of fan 1 | ||||
|             //TODO: only allow on platforms like addw2 | ||||
|             DCR4 = smfi_cmd[SMFI_CMD_DATA + 1]; | ||||
|             return RES_OK; | ||||
|     case 0: | ||||
|         // Set duty cycle of fan 0 | ||||
|         DCR2 = smfi_cmd[SMFI_CMD_DATA + 1]; | ||||
|         return RES_OK; | ||||
|     case 1: | ||||
|         // Set duty cycle of fan 1 | ||||
|         //TODO: only allow on platforms like addw2 | ||||
|         DCR4 = smfi_cmd[SMFI_CMD_DATA + 1]; | ||||
|         return RES_OK; | ||||
|     } | ||||
|  | ||||
|     // Failed if fan not found | ||||
| @@ -168,8 +168,7 @@ static enum Result cmd_keymap_set(void) { | ||||
|     int16_t layer = smfi_cmd[SMFI_CMD_DATA]; | ||||
|     int16_t output = smfi_cmd[SMFI_CMD_DATA + 1]; | ||||
|     int16_t input = smfi_cmd[SMFI_CMD_DATA + 2]; | ||||
|     uint16_t key = | ||||
|         ((uint16_t)smfi_cmd[SMFI_CMD_DATA + 3]) | | ||||
|     uint16_t key = ((uint16_t)smfi_cmd[SMFI_CMD_DATA + 3]) | | ||||
|         (((uint16_t)smfi_cmd[SMFI_CMD_DATA + 4]) << 8); | ||||
|     //TODO: consider only setting if the key has changed | ||||
|     if (keymap_set(layer, output, input, key)) { | ||||
| @@ -321,67 +320,67 @@ void smfi_event(void) { | ||||
|  | ||||
|         switch (smfi_cmd[SMFI_CMD_CMD]) { | ||||
| #if !defined(__SCRATCH__) | ||||
|             case CMD_PROBE: | ||||
|                 // Signature | ||||
|                 smfi_cmd[SMFI_CMD_DATA + 0] = 0x76; | ||||
|                 smfi_cmd[SMFI_CMD_DATA + 1] = 0xEC; | ||||
|                 // Version | ||||
|                 smfi_cmd[SMFI_CMD_DATA + 2] = 0x01; | ||||
|                 //TODO: bitmask of implemented commands? | ||||
|                 // Always successful | ||||
|                 smfi_cmd[SMFI_CMD_RES] = RES_OK; | ||||
|                 break; | ||||
|             case CMD_BOARD: | ||||
|                 strncpy(&smfi_cmd[SMFI_CMD_DATA], board(), ARRAY_SIZE(smfi_cmd) - SMFI_CMD_DATA); | ||||
|                 // Always successful | ||||
|                 smfi_cmd[SMFI_CMD_RES] = RES_OK; | ||||
|                 break; | ||||
|             case CMD_VERSION: | ||||
|                 strncpy(&smfi_cmd[SMFI_CMD_DATA], version(), ARRAY_SIZE(smfi_cmd) - SMFI_CMD_DATA); | ||||
|                 // Always successful | ||||
|                 smfi_cmd[SMFI_CMD_RES] = RES_OK; | ||||
|                 break; | ||||
|             case CMD_PRINT: | ||||
|                 smfi_cmd[SMFI_CMD_RES] = cmd_print(); | ||||
|                 break; | ||||
|             case CMD_FAN_GET: | ||||
|                 smfi_cmd[SMFI_CMD_RES] = cmd_fan_get(); | ||||
|                 break; | ||||
|             case CMD_FAN_SET: | ||||
|                 smfi_cmd[SMFI_CMD_RES] = cmd_fan_set(); | ||||
|                 break; | ||||
|             case CMD_KEYMAP_GET: | ||||
|                 smfi_cmd[SMFI_CMD_RES] = cmd_keymap_get(); | ||||
|                 break; | ||||
|             case CMD_KEYMAP_SET: | ||||
|                 smfi_cmd[SMFI_CMD_RES] = cmd_keymap_set(); | ||||
|                 break; | ||||
|             case CMD_LED_GET_VALUE: | ||||
|                 smfi_cmd[SMFI_CMD_RES] = cmd_led_get_value(); | ||||
|                 break; | ||||
|             case CMD_LED_SET_VALUE: | ||||
|                 smfi_cmd[SMFI_CMD_RES] = cmd_led_set_value(); | ||||
|                 break; | ||||
|             case CMD_LED_GET_COLOR: | ||||
|                 smfi_cmd[SMFI_CMD_RES] = cmd_led_get_color(); | ||||
|                 break; | ||||
|             case CMD_LED_SET_COLOR: | ||||
|                 smfi_cmd[SMFI_CMD_RES] = cmd_led_set_color(); | ||||
|                 break; | ||||
|             case CMD_MATRIX_GET: | ||||
|                 smfi_cmd[SMFI_CMD_RES] = cmd_matrix_get(); | ||||
|                 break; | ||||
|         case CMD_PROBE: | ||||
|             // Signature | ||||
|             smfi_cmd[SMFI_CMD_DATA + 0] = 0x76; | ||||
|             smfi_cmd[SMFI_CMD_DATA + 1] = 0xEC; | ||||
|             // Version | ||||
|             smfi_cmd[SMFI_CMD_DATA + 2] = 0x01; | ||||
|             //TODO: bitmask of implemented commands? | ||||
|             // Always successful | ||||
|             smfi_cmd[SMFI_CMD_RES] = RES_OK; | ||||
|             break; | ||||
|         case CMD_BOARD: | ||||
|             strncpy(&smfi_cmd[SMFI_CMD_DATA], board(), ARRAY_SIZE(smfi_cmd) - SMFI_CMD_DATA); | ||||
|             // Always successful | ||||
|             smfi_cmd[SMFI_CMD_RES] = RES_OK; | ||||
|             break; | ||||
|         case CMD_VERSION: | ||||
|             strncpy(&smfi_cmd[SMFI_CMD_DATA], version(), ARRAY_SIZE(smfi_cmd) - SMFI_CMD_DATA); | ||||
|             // Always successful | ||||
|             smfi_cmd[SMFI_CMD_RES] = RES_OK; | ||||
|             break; | ||||
|         case CMD_PRINT: | ||||
|             smfi_cmd[SMFI_CMD_RES] = cmd_print(); | ||||
|             break; | ||||
|         case CMD_FAN_GET: | ||||
|             smfi_cmd[SMFI_CMD_RES] = cmd_fan_get(); | ||||
|             break; | ||||
|         case CMD_FAN_SET: | ||||
|             smfi_cmd[SMFI_CMD_RES] = cmd_fan_set(); | ||||
|             break; | ||||
|         case CMD_KEYMAP_GET: | ||||
|             smfi_cmd[SMFI_CMD_RES] = cmd_keymap_get(); | ||||
|             break; | ||||
|         case CMD_KEYMAP_SET: | ||||
|             smfi_cmd[SMFI_CMD_RES] = cmd_keymap_set(); | ||||
|             break; | ||||
|         case CMD_LED_GET_VALUE: | ||||
|             smfi_cmd[SMFI_CMD_RES] = cmd_led_get_value(); | ||||
|             break; | ||||
|         case CMD_LED_SET_VALUE: | ||||
|             smfi_cmd[SMFI_CMD_RES] = cmd_led_set_value(); | ||||
|             break; | ||||
|         case CMD_LED_GET_COLOR: | ||||
|             smfi_cmd[SMFI_CMD_RES] = cmd_led_get_color(); | ||||
|             break; | ||||
|         case CMD_LED_SET_COLOR: | ||||
|             smfi_cmd[SMFI_CMD_RES] = cmd_led_set_color(); | ||||
|             break; | ||||
|         case CMD_MATRIX_GET: | ||||
|             smfi_cmd[SMFI_CMD_RES] = cmd_matrix_get(); | ||||
|             break; | ||||
| #endif // !defined(__SCRATCH__) | ||||
|             case CMD_SPI: | ||||
|                 smfi_cmd[SMFI_CMD_RES] = cmd_spi(); | ||||
|                 break; | ||||
|             case CMD_RESET: | ||||
|                 smfi_cmd[SMFI_CMD_RES] = cmd_reset(); | ||||
|                 break; | ||||
|             default: | ||||
|                 // Command not found | ||||
|                 smfi_cmd[SMFI_CMD_RES] = RES_ERR; | ||||
|                 break; | ||||
|         case CMD_SPI: | ||||
|             smfi_cmd[SMFI_CMD_RES] = cmd_spi(); | ||||
|             break; | ||||
|         case CMD_RESET: | ||||
|             smfi_cmd[SMFI_CMD_RES] = cmd_reset(); | ||||
|             break; | ||||
|         default: | ||||
|             // Command not found | ||||
|             smfi_cmd[SMFI_CMD_RES] = RES_ERR; | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         // Mark command as finished | ||||
|   | ||||
| @@ -5,15 +5,15 @@ | ||||
| #include <board/smfi.h> | ||||
|  | ||||
| #ifdef SERIAL_DEBUGGER | ||||
|     #include <mcs51/8051.h> | ||||
| #include <mcs51/8051.h> | ||||
| #endif | ||||
|  | ||||
| #ifdef I2C_DEBUGGER | ||||
|     #include <ec/i2c.h> | ||||
| #include <ec/i2c.h> | ||||
| #endif | ||||
|  | ||||
| #ifdef PARALLEL_DEBUG | ||||
|     #include <board/parallel.h> | ||||
| #include <board/parallel.h> | ||||
| #endif // PARALLEL_DEBUG | ||||
|  | ||||
| int putchar(int c) { | ||||
|   | ||||
| @@ -4,13 +4,13 @@ | ||||
| #include <board/wireless.h> | ||||
|  | ||||
| #ifndef HAVE_BT_EN | ||||
|     #define HAVE_BT_EN 1 | ||||
| #define HAVE_BT_EN 1 | ||||
| #endif | ||||
| #ifndef HAVE_WLAN_EN | ||||
|     #define HAVE_WLAN_EN 1 | ||||
| #define HAVE_WLAN_EN 1 | ||||
| #endif | ||||
| #ifndef HAVE_WLAN_PWR_EN | ||||
|     #define HAVE_WLAN_PWR_EN 1 | ||||
| #define HAVE_WLAN_PWR_EN 1 | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -242,13 +242,13 @@ void gpio_init() { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n", | ||||
|             bank, | ||||
| @@ -262,7 +262,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -273,6 +273,6 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #undef bank | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -39,7 +39,7 @@ struct Gpio __code VA_EC_EN =       GPIO(J, 4); | ||||
| struct Gpio __code WLAN_EN =        GPIO(G, 1); | ||||
| struct Gpio __code WLAN_PWR_EN =    GPIO(A, 3); | ||||
| struct Gpio __code XLP_OUT =        GPIO(B, 4); | ||||
| // clange-format on | ||||
| // clang-format on | ||||
|  | ||||
| void gpio_init() { | ||||
|     // Enable LPC reset on GPD2 | ||||
| @@ -251,13 +251,13 @@ void gpio_init() { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d: data %d mirror %d pot %d control %02X\n", | ||||
|             bank, | ||||
| @@ -271,7 +271,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -282,9 +282,9 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #define GPOTM 0 | ||||
| #define GPOTM 0 | ||||
|     bank(M); | ||||
|     #undef GPOTM | ||||
|     #undef bank | ||||
| #undef GPOTM | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -36,7 +36,7 @@ struct Gpio __code VA_EC_EN =       GPIO(J, 4); | ||||
| struct Gpio __code WLAN_EN =        GPIO(F, 3); | ||||
| struct Gpio __code WLAN_PWR_EN =    GPIO(G, 1); | ||||
| struct Gpio __code XLP_OUT =        GPIO(B, 4); | ||||
| // clange-format on | ||||
| // clang-format on | ||||
|  | ||||
| void gpio_init(void) { | ||||
|     // PWRSW WDT 2 Enable 2 | ||||
| @@ -258,13 +258,13 @@ void gpio_init(void) { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d: data %d mirror %d pot %d control %02X\n", | ||||
|             bank, | ||||
| @@ -278,7 +278,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -289,9 +289,9 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #define GPOTM 0 | ||||
| #define GPOTM 0 | ||||
|     bank(M); | ||||
|     #undef GPOTM | ||||
|     #undef bank | ||||
| #undef GPOTM | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -242,13 +242,13 @@ void gpio_init() { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n", | ||||
|             bank, | ||||
| @@ -262,7 +262,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -273,6 +273,6 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #undef bank | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -253,13 +253,13 @@ void gpio_init() { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d: data %d mirror %d pot %d control %02X\n", | ||||
|             bank, | ||||
| @@ -273,7 +273,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -284,9 +284,9 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #define GPOTM 0 | ||||
| #define GPOTM 0 | ||||
|     bank(M); | ||||
|     #undef GPOTM | ||||
|     #undef bank | ||||
| #undef GPOTM | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -262,13 +262,13 @@ void gpio_init(void) { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d: data %d mirror %d pot %d control %02X\n", | ||||
|             bank, | ||||
| @@ -282,7 +282,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -293,9 +293,9 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #define GPOTM 0 | ||||
| #define GPOTM 0 | ||||
|     bank(M); | ||||
|     #undef GPOTM | ||||
|     #undef bank | ||||
| #undef GPOTM | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -241,13 +241,13 @@ void gpio_init() { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n", | ||||
|             bank, | ||||
| @@ -261,7 +261,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -272,6 +272,6 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #undef bank | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| #include <board/gpio.h> | ||||
| #include <common/debug.h> | ||||
|  | ||||
| // clang-format off | ||||
| struct Gpio __code ACIN_N =         GPIO(B, 0); | ||||
| struct Gpio __code AC_PRESENT =     GPIO(E, 1); | ||||
| struct Gpio __code ALL_SYS_PWRGD =  GPIO(C, 0); | ||||
| @@ -33,6 +34,7 @@ struct Gpio __code VA_EC_EN =       GPIO(J, 4); | ||||
| struct Gpio __code WLAN_EN =        GPIO(G, 1); | ||||
| struct Gpio __code WLAN_PWR_EN =    GPIO(A, 3); | ||||
| struct Gpio __code XLP_OUT =        GPIO(B, 4); | ||||
| // clang-format on | ||||
|  | ||||
| void gpio_init() { | ||||
|     // Enable LPC reset on GPD2 | ||||
| @@ -244,13 +246,13 @@ void gpio_init() { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n", | ||||
|             bank, | ||||
| @@ -264,7 +266,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -275,6 +277,6 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #undef bank | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| #include <board/gpio.h> | ||||
| #include <common/debug.h> | ||||
|  | ||||
| // clang-format off | ||||
| struct Gpio __code ACIN_N =         GPIO(B, 0); | ||||
| struct Gpio __code AC_PRESENT =     GPIO(E, 1); | ||||
| struct Gpio __code ALL_SYS_PWRGD =  GPIO(C, 0); | ||||
| @@ -34,6 +35,7 @@ struct Gpio __code VA_EC_EN =       GPIO(J, 4); | ||||
| struct Gpio __code WLAN_EN =        GPIO(G, 1); | ||||
| struct Gpio __code WLAN_PWR_EN =    GPIO(A, 3); | ||||
| struct Gpio __code XLP_OUT =        GPIO(B, 4); | ||||
| // clang-format on | ||||
|  | ||||
| void gpio_init() { | ||||
|     // Enable LPC reset on GPD2 | ||||
| @@ -244,13 +246,13 @@ void gpio_init() { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n", | ||||
|             bank, | ||||
| @@ -264,7 +266,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -275,6 +277,6 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #undef bank | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| #include <board/gpio.h> | ||||
| #include <common/debug.h> | ||||
|  | ||||
| // clang-format off | ||||
| struct Gpio __code ACIN_N =         GPIO(B, 0); | ||||
| struct Gpio __code AC_PRESENT =     GPIO(E, 1); | ||||
| struct Gpio __code ALL_SYS_PWRGD =  GPIO(C, 0); | ||||
| @@ -33,6 +34,7 @@ struct Gpio __code VA_EC_EN =       GPIO(H, 7); | ||||
| struct Gpio __code WLAN_EN =        GPIO(G, 1); | ||||
| struct Gpio __code WLAN_PWR_EN =    GPIO(A, 3); | ||||
| struct Gpio __code XLP_OUT =        GPIO(B, 4); | ||||
| // clang-format on | ||||
|  | ||||
| void gpio_init() { | ||||
|     // Enable LPC reset on GPD2 | ||||
| @@ -242,13 +244,13 @@ void gpio_init() { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n", | ||||
|             bank, | ||||
| @@ -262,7 +264,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -273,6 +275,6 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #undef bank | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| #include <board/gpio.h> | ||||
| #include <common/debug.h> | ||||
|  | ||||
| // clang-format off | ||||
| struct Gpio __code ACIN_N =         GPIO(B, 0); | ||||
| struct Gpio __code AC_PRESENT =     GPIO(E, 1); | ||||
| struct Gpio __code ALL_SYS_PWRGD =  GPIO(C, 0); | ||||
| @@ -33,6 +34,7 @@ struct Gpio __code VA_EC_EN =       GPIO(J, 4); | ||||
| struct Gpio __code WLAN_EN =        GPIO(G, 1); | ||||
| struct Gpio __code WLAN_PWR_EN =    GPIO(D, 3); | ||||
| struct Gpio __code XLP_OUT =        GPIO(B, 4); | ||||
| // clang-format on | ||||
|  | ||||
| void gpio_init() { | ||||
|     // Enable LPC reset on GPD2 | ||||
| @@ -248,13 +250,13 @@ void gpio_init() { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n", | ||||
|             bank, | ||||
| @@ -268,7 +270,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -279,6 +281,6 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #undef bank | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -250,13 +250,13 @@ void gpio_init() { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d: data %d mirror %d pot %d control %02X\n", | ||||
|             bank, | ||||
| @@ -270,7 +270,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -281,9 +281,9 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #define GPOTM 0 | ||||
| #define GPOTM 0 | ||||
|     bank(M); | ||||
|     #undef GPOTM | ||||
|     #undef bank | ||||
| #undef GPOTM | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -6,7 +6,6 @@ | ||||
| #include <board/gpio.h> | ||||
| #include <ec/ec.h> | ||||
|  | ||||
|  | ||||
| void board_init(void) { | ||||
|     espi_init(); | ||||
|  | ||||
|   | ||||
| @@ -36,7 +36,7 @@ struct Gpio __code VA_EC_EN =       GPIO(J, 4); | ||||
| struct Gpio __code WLAN_EN =        GPIO(G, 1); | ||||
| struct Gpio __code WLAN_PWR_EN =    GPIO(A, 3); | ||||
| struct Gpio __code XLP_OUT =        GPIO(B, 4); | ||||
| // clange-format on | ||||
| // clang-format on | ||||
|  | ||||
| void gpio_init(void) { | ||||
|     // Not documented | ||||
| @@ -262,13 +262,13 @@ void gpio_init(void) { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d: data %d mirror %d pot %d control %02X\n", | ||||
|             bank, | ||||
| @@ -282,7 +282,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -293,9 +293,9 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #define GPOTM 0 | ||||
| #define GPOTM 0 | ||||
|     bank(M); | ||||
|     #undef GPOTM | ||||
|     #undef bank | ||||
| #undef GPOTM | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -18,6 +18,9 @@ void board_init(void) { | ||||
|     gpio_set(&SWI_N, true); | ||||
| } | ||||
|  | ||||
| void board_on_ac(bool ac) { /* Fix unused variable */ ac = ac; } | ||||
| void board_on_ac(bool ac) { | ||||
|     /* Fix unused variable */ | ||||
|     ac = ac; | ||||
| } | ||||
|  | ||||
| void board_event(void) {} | ||||
|   | ||||
| @@ -240,13 +240,13 @@ void gpio_init() { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n", | ||||
|             bank, | ||||
| @@ -260,7 +260,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -271,6 +271,6 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #undef bank | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -247,13 +247,13 @@ void gpio_init(void) { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n", | ||||
|             bank, | ||||
| @@ -267,7 +267,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -278,6 +278,6 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #undef bank | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -245,13 +245,13 @@ void gpio_init() { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n", | ||||
|             bank, | ||||
| @@ -265,7 +265,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -276,6 +276,6 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #undef bank | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -244,13 +244,13 @@ void gpio_init() { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n", | ||||
|             bank, | ||||
| @@ -264,7 +264,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -275,6 +275,6 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #undef bank | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| #include <board/gpio.h> | ||||
| #include <common/debug.h> | ||||
|  | ||||
| // clang-format off | ||||
| struct Gpio __code ACIN_N =         GPIO(B, 0); | ||||
| struct Gpio __code AC_PRESENT =     GPIO(E, 1); | ||||
| struct Gpio __code ALL_SYS_PWRGD =  GPIO(C, 0); | ||||
| @@ -32,6 +33,7 @@ struct Gpio __code VA_EC_EN =       GPIO(J, 4); // renamed to EC_SLP_SUS# | ||||
| struct Gpio __code WLAN_EN =        GPIO(G, 1); | ||||
| struct Gpio __code WLAN_PWR_EN =    GPIO(H, 4); | ||||
| struct Gpio __code XLP_OUT =        GPIO(B, 4); | ||||
| // clang-format on | ||||
|  | ||||
| void gpio_init() { | ||||
|     // Enable LPC reset on GPD2 | ||||
| @@ -244,13 +246,13 @@ void gpio_init() { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n", | ||||
|             bank, | ||||
| @@ -264,7 +266,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -275,6 +277,6 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #undef bank | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -261,13 +261,13 @@ void gpio_init(void) { | ||||
|  | ||||
| #if GPIO_DEBUG | ||||
| void gpio_debug_bank( | ||||
|     char * bank, | ||||
|     char *bank, | ||||
|     uint8_t data, | ||||
|     uint8_t mirror, | ||||
|     uint8_t pot, | ||||
|     volatile uint8_t * control | ||||
|     volatile uint8_t *control | ||||
| ) { | ||||
|     for(char i = 0; i < 8; i++) { | ||||
|     for (char i = 0; i < 8; i++) { | ||||
|         DEBUG( | ||||
|             "%s%d: data %d mirror %d pot %d control %02X\n", | ||||
|             bank, | ||||
| @@ -281,7 +281,7 @@ void gpio_debug_bank( | ||||
| } | ||||
|  | ||||
| void gpio_debug(void) { | ||||
|     #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) | ||||
| #define bank(BANK) gpio_debug_bank(#BANK, GPDR##BANK, GPDMR##BANK, GPOT##BANK, &GPCR##BANK##0) | ||||
|     bank(A); | ||||
|     bank(B); | ||||
|     bank(C); | ||||
| @@ -292,9 +292,9 @@ void gpio_debug(void) { | ||||
|     bank(H); | ||||
|     bank(I); | ||||
|     bank(J); | ||||
|     #define GPOTM 0 | ||||
| #define GPOTM 0 | ||||
|     bank(M); | ||||
|     #undef GPOTM | ||||
|     #undef bank | ||||
| #undef GPOTM | ||||
| #undef bank | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -2,54 +2,64 @@ | ||||
|  | ||||
| #include <common/i2c.h> | ||||
|  | ||||
| int16_t i2c_recv(struct I2C * i2c, uint8_t addr, uint8_t* data, uint16_t length) __reentrant { | ||||
| int16_t i2c_recv(struct I2C *i2c, uint8_t addr, uint8_t *data, uint16_t length) __reentrant { | ||||
|     int16_t res = 0; | ||||
|  | ||||
|     res = i2c_start(i2c, addr, true); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     res = i2c_read(i2c, data, length); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     i2c_stop(i2c); | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| int16_t i2c_send(struct I2C * i2c, uint8_t addr, uint8_t* data, uint16_t length) __reentrant { | ||||
| int16_t i2c_send(struct I2C *i2c, uint8_t addr, uint8_t *data, uint16_t length) __reentrant { | ||||
|     int16_t res = 0; | ||||
|  | ||||
|     res = i2c_start(i2c, addr, false); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     res = i2c_write(i2c, data, length); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     i2c_stop(i2c); | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| int16_t i2c_get(struct I2C * i2c, uint8_t addr, uint8_t reg, uint8_t* data, uint16_t length) __reentrant { | ||||
| int16_t i2c_get(struct I2C *i2c, uint8_t addr, uint8_t reg, uint8_t *data, uint16_t length) | ||||
|     __reentrant { | ||||
|     int16_t res = 0; | ||||
|  | ||||
|     res = i2c_start(i2c, addr, false); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     res = i2c_write(i2c, ®, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     return i2c_recv(i2c, addr, data, length); | ||||
| } | ||||
|  | ||||
| int16_t i2c_set(struct I2C * i2c, uint8_t addr, uint8_t reg, uint8_t* data, uint16_t length) __reentrant { | ||||
| int16_t i2c_set(struct I2C *i2c, uint8_t addr, uint8_t reg, uint8_t *data, uint16_t length) | ||||
|     __reentrant { | ||||
|     int16_t res = 0; | ||||
|  | ||||
|     res = i2c_start(i2c, addr, false); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     res = i2c_write(i2c, ®, 1); | ||||
|     if (res < 0) return res; | ||||
|     if (res < 0) | ||||
|         return res; | ||||
|  | ||||
|     return i2c_send(i2c, addr, data, length); | ||||
| } | ||||
|   | ||||
| @@ -14,37 +14,37 @@ | ||||
|  | ||||
| // This is the user-configurable log level | ||||
| #ifndef LEVEL | ||||
|     #define LEVEL LEVEL_INFO | ||||
| #define LEVEL LEVEL_INFO | ||||
| #endif | ||||
|  | ||||
| #if LEVEL >= LEVEL_TRACE | ||||
|     #define TRACE(...) printf(__VA_ARGS__) | ||||
| #define TRACE(...) printf(__VA_ARGS__) | ||||
| #else | ||||
|     #define TRACE(...) | ||||
| #define TRACE(...) | ||||
| #endif | ||||
|  | ||||
| #if LEVEL >= LEVEL_DEBUG | ||||
|     #define DEBUG(...) printf(__VA_ARGS__) | ||||
| #define DEBUG(...) printf(__VA_ARGS__) | ||||
| #else | ||||
|     #define DEBUG(...) | ||||
| #define DEBUG(...) | ||||
| #endif | ||||
|  | ||||
| #if LEVEL >= LEVEL_INFO | ||||
|     #define INFO(...) printf(__VA_ARGS__) | ||||
| #define INFO(...) printf(__VA_ARGS__) | ||||
| #else | ||||
|     #define INFO(...) | ||||
| #define INFO(...) | ||||
| #endif | ||||
|  | ||||
| #if LEVEL >= LEVEL_WARN | ||||
|     #define WARN(...) printf(__VA_ARGS__) | ||||
| #define WARN(...) printf(__VA_ARGS__) | ||||
| #else | ||||
|     #define WARN(...) | ||||
| #define WARN(...) | ||||
| #endif | ||||
|  | ||||
| #if LEVEL >= LEVEL_ERROR | ||||
|     #define ERROR(...) printf(__VA_ARGS__) | ||||
| #define ERROR(...) printf(__VA_ARGS__) | ||||
| #else | ||||
|     #define ERROR(...) | ||||
| #define ERROR(...) | ||||
| #endif | ||||
|  | ||||
| #endif // _COMMON_DEBUG_H | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|  | ||||
| // Prevent failures to compile on AVR | ||||
| #ifndef __SDCC | ||||
|     #define __reentrant | ||||
| #define __reentrant | ||||
| #endif | ||||
|  | ||||
| // I2C bus, should be defined elsewhere | ||||
| @@ -16,30 +16,34 @@ struct I2C; | ||||
|  | ||||
| // Start i2c transaction | ||||
| // Must be defined by arch, board, or ec | ||||
| int16_t i2c_start(struct I2C * i2c, uint8_t addr, bool read) __reentrant; | ||||
| int16_t i2c_start(struct I2C *i2c, uint8_t addr, bool read) __reentrant; | ||||
|  | ||||
| // Stop i2c transaction | ||||
| // Must be defined by arch, board, or ec | ||||
| void i2c_stop(struct I2C * i2c) __reentrant; | ||||
| void i2c_stop(struct I2C *i2c) __reentrant; | ||||
|  | ||||
| // Send a byte on i2c bus | ||||
| // Must be defined by arch, board, or ec | ||||
| int16_t i2c_write(struct I2C * i2c, uint8_t * data, uint16_t length) __reentrant; | ||||
| int16_t i2c_write(struct I2C *i2c, uint8_t *data, uint16_t length) __reentrant; | ||||
|  | ||||
| // Read bytes from bus | ||||
| // Must be defined by arch, board, or ec | ||||
| int16_t i2c_read(struct I2C * i2c, uint8_t * data, uint16_t length) __reentrant; | ||||
| int16_t i2c_read(struct I2C *i2c, uint8_t *data, uint16_t length) __reentrant; | ||||
|  | ||||
| // Read multiple bytes from address in one transaction | ||||
| int16_t i2c_recv(struct I2C * i2c, uint8_t addr, uint8_t* data, uint16_t length) __reentrant; | ||||
| int16_t i2c_recv(struct I2C *i2c, uint8_t addr, uint8_t *data, uint16_t length) __reentrant; | ||||
|  | ||||
| // Write multiple bytes to address in one transaction | ||||
| int16_t i2c_send(struct I2C * i2c, uint8_t addr, uint8_t* data, uint16_t length) __reentrant; | ||||
| int16_t i2c_send(struct I2C *i2c, uint8_t addr, uint8_t *data, uint16_t length) __reentrant; | ||||
|  | ||||
| // clang-format off | ||||
|  | ||||
| // Read multiple bytes from a register in one transaction | ||||
| int16_t i2c_get(struct I2C * i2c, uint8_t addr, uint8_t reg, uint8_t* data, uint16_t length) __reentrant; | ||||
| int16_t i2c_get(struct I2C *i2c, uint8_t addr, uint8_t reg, uint8_t *data, uint16_t length) __reentrant; | ||||
|  | ||||
| // Write multiple bytes to a register in one transaction | ||||
| int16_t i2c_set(struct I2C * i2c, uint8_t addr, uint8_t reg, uint8_t* data, uint16_t length) __reentrant; | ||||
| int16_t i2c_set(struct I2C *i2c, uint8_t addr, uint8_t reg, uint8_t *data, uint16_t length) __reentrant; | ||||
|  | ||||
| // clang-format on | ||||
|  | ||||
| #endif // _COMMON_I2C_H | ||||
|   | ||||
| @@ -8,28 +8,28 @@ | ||||
|  | ||||
| // Keymap defined by board | ||||
| #if defined(KM_LAY) && defined(KM_OUT) && defined(KM_IN) | ||||
|     extern uint16_t __code KEYMAP[KM_LAY][KM_OUT][KM_IN]; | ||||
|     extern uint16_t __xdata DYNAMIC_KEYMAP[KM_LAY][KM_OUT][KM_IN]; | ||||
|     #define HAVE_KEYMAP 1 | ||||
| extern uint16_t __code KEYMAP[KM_LAY][KM_OUT][KM_IN]; | ||||
| extern uint16_t __xdata DYNAMIC_KEYMAP[KM_LAY][KM_OUT][KM_IN]; | ||||
| #define HAVE_KEYMAP 1 | ||||
| #else | ||||
|     #define HAVE_KEYMAP 0 | ||||
| #define HAVE_KEYMAP 0 | ||||
| #endif | ||||
|  | ||||
| #if HAVE_KEYMAP | ||||
|     // Initialize the dynamic keymap | ||||
|     void keymap_init(void); | ||||
|     // Set the dynamic keymap to the default keymap | ||||
|     void keymap_load_default(void); | ||||
|     // Erase dynamic keymap in flash | ||||
|     bool keymap_erase_config(void); | ||||
|     // Load dynamic keymap from flash | ||||
|     bool keymap_load_config(void); | ||||
|     // Save dynamic keymap to flash | ||||
|     bool keymap_save_config(void); | ||||
|     // Get a keycode from the dynamic keymap | ||||
|     bool keymap_get(uint8_t layer, uint8_t output, uint8_t input, uint16_t * value); | ||||
|     // Set a keycode in the dynamic keymap | ||||
|     bool keymap_set(uint8_t layer, uint8_t output, uint8_t input, uint16_t value); | ||||
| // Initialize the dynamic keymap | ||||
| void keymap_init(void); | ||||
| // Set the dynamic keymap to the default keymap | ||||
| void keymap_load_default(void); | ||||
| // Erase dynamic keymap in flash | ||||
| bool keymap_erase_config(void); | ||||
| // Load dynamic keymap from flash | ||||
| bool keymap_load_config(void); | ||||
| // Save dynamic keymap to flash | ||||
| bool keymap_save_config(void); | ||||
| // Get a keycode from the dynamic keymap | ||||
| bool keymap_get(uint8_t layer, uint8_t output, uint8_t input, uint16_t *value); | ||||
| // Set a keycode in the dynamic keymap | ||||
| bool keymap_set(uint8_t layer, uint8_t output, uint8_t input, uint16_t value); | ||||
| #endif | ||||
|  | ||||
| // Translate a keycode from PS/2 set 2 to PS/2 set 1 | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
| #define _COMMON_MACRO_H | ||||
|  | ||||
| #define xconcat(a, b) concat(a, b) | ||||
| #define concat(a, b) a ## b | ||||
| #define concat(a, b) a##b | ||||
|  | ||||
| #define xstr(s) str(s) | ||||
| #define str(s) #s | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| #ifndef _COMMON_VERSION_H | ||||
| #define _COMMON_VERSION_H | ||||
|  | ||||
| const char * board(); | ||||
| const char * version(); | ||||
| const char *board(); | ||||
| const char *version(); | ||||
|  | ||||
| #endif // _COMMON_VERSION_H | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| // Prevent failures to compile on AVR | ||||
| //TODO: move to a driver included only on platforms needing it | ||||
| #ifndef __SDCC | ||||
|     #define __code | ||||
| #define __code | ||||
| #endif | ||||
|  | ||||
| // https://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html#ss10.3 | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| // Prevent failures to compile on AVR | ||||
| #ifndef __SDCC | ||||
|     #define __code | ||||
| #define __code | ||||
| #endif | ||||
|  | ||||
| // clang-format off | ||||
| @@ -17,10 +17,10 @@ static const char __code VERSION[] = | ||||
|     xstr(__FIRMWARE_VERSION__); | ||||
| // clang-format on | ||||
|  | ||||
| const char * board() { | ||||
| const char *board() { | ||||
|     return &BOARD[11]; | ||||
| } | ||||
|  | ||||
| const char * version() { | ||||
| const char *version() { | ||||
|     return &VERSION[13]; | ||||
| } | ||||
|   | ||||
| @@ -35,30 +35,30 @@ struct VirtualWire __code VW_SUS_ACK_N = VIRTUAL_WIRE(40, 0); | ||||
| struct VirtualWire __code VW_SUS_WARN_N = VIRTUAL_WIRE(41, 0); | ||||
| struct VirtualWire __code VW_SUS_PWRDN_ACK = VIRTUAL_WIRE(41, 1); | ||||
|  | ||||
| enum VirtualWireState vw_get(struct VirtualWire * vw) __critical { | ||||
| enum VirtualWireState vw_get(struct VirtualWire *vw) __critical { | ||||
|     uint8_t index = *vw->index; | ||||
|     switch ((index >> vw->shift) & VWS_HIGH) { | ||||
|         case VWS_LOW: | ||||
|             return VWS_LOW; | ||||
|         case VWS_HIGH: | ||||
|             return VWS_HIGH; | ||||
|         default: | ||||
|             return VWS_INVALID; | ||||
|     case VWS_LOW: | ||||
|         return VWS_LOW; | ||||
|     case VWS_HIGH: | ||||
|         return VWS_HIGH; | ||||
|     default: | ||||
|         return VWS_INVALID; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void vw_set(struct VirtualWire * vw, enum VirtualWireState state) __critical { | ||||
| void vw_set(struct VirtualWire *vw, enum VirtualWireState state) __critical { | ||||
|     uint8_t index = *vw->index; | ||||
|     index &= ~(VWS_HIGH << vw->shift); | ||||
|     switch (state) { | ||||
|         case VWS_LOW: | ||||
|             index |= VWS_LOW << vw->shift; | ||||
|             break; | ||||
|         case VWS_HIGH: | ||||
|             index |= VWS_HIGH << vw->shift; | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|     case VWS_LOW: | ||||
|         index |= VWS_LOW << vw->shift; | ||||
|         break; | ||||
|     case VWS_HIGH: | ||||
|         index |= VWS_HIGH << vw->shift; | ||||
|         break; | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
|     *vw->index = index; | ||||
| } | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  | ||||
| #include <ec/gpio.h> | ||||
|  | ||||
| bool gpio_get(struct Gpio * gpio) { | ||||
| bool gpio_get(struct Gpio *gpio) { | ||||
|     if (*(gpio->data) & gpio->value) { | ||||
|         return true; | ||||
|     } else { | ||||
| @@ -10,7 +10,7 @@ bool gpio_get(struct Gpio * gpio) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| void gpio_set(struct Gpio * gpio, bool value) { | ||||
| void gpio_set(struct Gpio *gpio, bool value) { | ||||
|     if (value) { | ||||
|         *(gpio->data) |= gpio->value; | ||||
|     } else { | ||||
|   | ||||
| @@ -9,11 +9,11 @@ | ||||
| #define I2C_TIMEOUT 10000 | ||||
|  | ||||
| struct I2C { | ||||
|     volatile uint8_t * hosta; | ||||
|     volatile uint8_t * hoctl; | ||||
|     volatile uint8_t * hoctl2; | ||||
|     volatile uint8_t * hobdb; | ||||
|     volatile uint8_t * trasla; | ||||
|     volatile uint8_t *hosta; | ||||
|     volatile uint8_t *hoctl; | ||||
|     volatile uint8_t *hoctl2; | ||||
|     volatile uint8_t *hobdb; | ||||
|     volatile uint8_t *trasla; | ||||
| }; | ||||
|  | ||||
| struct I2C __code I2C_0 = { | ||||
| @@ -42,10 +42,11 @@ struct I2C __code I2C_4 = { | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| void i2c_reset(struct I2C * i2c, bool kill) { | ||||
| void i2c_reset(struct I2C *i2c, bool kill) { | ||||
|     if (*(i2c->hosta) & HOSTA_BUSY) { | ||||
|         // Set kill bit | ||||
|         if (kill) *(i2c->hoctl) |= BIT(1); | ||||
|         if (kill) | ||||
|             *(i2c->hoctl) |= BIT(1); | ||||
|         // Wait for host to finish | ||||
|         while (*(i2c->hosta) & HOSTA_BUSY) {} | ||||
|     } | ||||
| @@ -57,7 +58,7 @@ void i2c_reset(struct I2C * i2c, bool kill) { | ||||
|     *(i2c->hoctl2) = 0; | ||||
| } | ||||
|  | ||||
| int16_t i2c_start(struct I2C * i2c, uint8_t addr, bool read) __reentrant { | ||||
| int16_t i2c_start(struct I2C *i2c, uint8_t addr, bool read) __reentrant { | ||||
|     // If we are already in a transaction | ||||
|     if (*(i2c->hosta) & HOSTA_BYTE_DONE) { | ||||
|         // If we are switching direction | ||||
| @@ -85,7 +86,7 @@ int16_t i2c_start(struct I2C * i2c, uint8_t addr, bool read) __reentrant { | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| void i2c_stop(struct I2C * i2c) { | ||||
| void i2c_stop(struct I2C *i2c) { | ||||
|     // Disable i2c compatibility | ||||
|     *(i2c->hoctl2) &= ~BIT(1); | ||||
|     // Clear status | ||||
| @@ -94,7 +95,7 @@ void i2c_stop(struct I2C * i2c) { | ||||
|     i2c_reset(i2c, false); | ||||
| } | ||||
|  | ||||
| static int16_t i2c_transaction(struct I2C * i2c, uint8_t * data, uint16_t length, bool read) { | ||||
| static int16_t i2c_transaction(struct I2C *i2c, uint8_t *data, uint16_t length, bool read) { | ||||
|     uint16_t i; | ||||
|     for (i = 0; i < length; i++) { | ||||
|         if (read) { | ||||
| @@ -126,17 +127,17 @@ static int16_t i2c_transaction(struct I2C * i2c, uint8_t * data, uint16_t length | ||||
|         // Wait for byte done, timeout, or error | ||||
|         uint8_t status; | ||||
|         uint32_t timeout = I2C_TIMEOUT; | ||||
|         for(timeout = I2C_TIMEOUT; timeout > 0; timeout--) { | ||||
|         for (timeout = I2C_TIMEOUT; timeout > 0; timeout--) { | ||||
|             status = *(i2c->hosta); | ||||
|             // If error occured, kill transaction and return error | ||||
|             if (status & HOSTA_ERR) { | ||||
|                 i2c_reset(i2c, true); | ||||
|                 return -(int16_t)(status); | ||||
|             } else | ||||
|             // If byte done, break | ||||
|             if (status & HOSTA_BYTE_DONE) { | ||||
|                 break; | ||||
|             } | ||||
|                 // If byte done, break | ||||
|                 if (status & HOSTA_BYTE_DONE) { | ||||
|                     break; | ||||
|                 } | ||||
|         } | ||||
|         // If timeout occured, kill transaction and return error | ||||
|         if (timeout == 0) { | ||||
| @@ -153,10 +154,10 @@ static int16_t i2c_transaction(struct I2C * i2c, uint8_t * data, uint16_t length | ||||
|     return i; | ||||
| } | ||||
|  | ||||
| int16_t i2c_read(struct I2C * i2c, uint8_t * data, uint16_t length) __reentrant { | ||||
| int16_t i2c_read(struct I2C *i2c, uint8_t *data, uint16_t length) __reentrant { | ||||
|     return i2c_transaction(i2c, data, length, true); | ||||
| } | ||||
|  | ||||
| int16_t i2c_write(struct I2C * i2c, uint8_t * data, uint16_t length) __reentrant { | ||||
| int16_t i2c_write(struct I2C *i2c, uint8_t *data, uint16_t length) __reentrant { | ||||
|     return i2c_transaction(i2c, data, length, false); | ||||
| } | ||||
|   | ||||
| @@ -6,7 +6,7 @@ | ||||
| #include <stdint.h> | ||||
|  | ||||
| struct VirtualWire { | ||||
|     volatile uint8_t __xdata * index; | ||||
|     volatile uint8_t __xdata *index; | ||||
|     uint8_t shift; | ||||
| }; | ||||
|  | ||||
| @@ -23,9 +23,9 @@ enum VirtualWireState { | ||||
|     VWS_HIGH = 0x11, | ||||
| }; | ||||
|  | ||||
| enum VirtualWireState vw_get(struct VirtualWire * vw) __critical; | ||||
| enum VirtualWireState vw_get(struct VirtualWire *vw) __critical; | ||||
|  | ||||
| void vw_set(struct VirtualWire * vw, enum VirtualWireState state) __critical; | ||||
| void vw_set(struct VirtualWire *vw, enum VirtualWireState state) __critical; | ||||
|  | ||||
| // Not all wires are defined or implemented | ||||
| // Index 2 - AP to EC | ||||
|   | ||||
| @@ -8,16 +8,18 @@ | ||||
| #include <stdbool.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| // clang-format off | ||||
| #define GPIO_ALT    (0b00U << 6) | ||||
| #define GPIO_IN     (0b10U << 6) | ||||
| #define GPIO_OUT    (0b01U << 6) | ||||
| #define GPIO_UP     BIT(2) | ||||
| #define GPIO_DOWN   BIT(1) | ||||
| // clang-format on | ||||
|  | ||||
| struct Gpio { | ||||
|     volatile uint8_t __xdata * data; | ||||
|     volatile uint8_t __xdata * mirror; | ||||
|     volatile uint8_t __xdata * control; | ||||
|     volatile uint8_t __xdata *data; | ||||
|     volatile uint8_t __xdata *mirror; | ||||
|     volatile uint8_t __xdata *control; | ||||
|     uint8_t value; | ||||
| }; | ||||
|  | ||||
| @@ -30,8 +32,8 @@ struct Gpio { | ||||
| } | ||||
| // clang-format on | ||||
|  | ||||
| bool gpio_get(struct Gpio * gpio); | ||||
| void gpio_set(struct Gpio * gpio, bool value); | ||||
| bool gpio_get(struct Gpio *gpio); | ||||
| void gpio_set(struct Gpio *gpio, bool value); | ||||
|  | ||||
| volatile uint8_t __xdata __at(0x1600) GCR; | ||||
| volatile uint8_t __xdata __at(0x16F0) GCR1; | ||||
|   | ||||
| @@ -11,6 +11,6 @@ extern struct I2C __code I2C_1; | ||||
| extern struct I2C __code I2C_4; | ||||
| #endif | ||||
|  | ||||
| void i2c_reset(struct I2C * i2c, bool kill); | ||||
| void i2c_reset(struct I2C *i2c, bool kill); | ||||
|  | ||||
| #endif // _EC_I2C_H | ||||
|   | ||||
| @@ -12,17 +12,17 @@ void kbc_init(void); | ||||
|  | ||||
| struct Kbc { | ||||
|     // Control register | ||||
|     volatile uint8_t * control; | ||||
|     volatile uint8_t *control; | ||||
|     // Interrupt control register | ||||
|     volatile uint8_t * irq; | ||||
|     volatile uint8_t *irq; | ||||
|     // Status register | ||||
|     volatile uint8_t * status; | ||||
|     volatile uint8_t *status; | ||||
|     // Keyboard out register | ||||
|     volatile uint8_t * keyboard_out; | ||||
|     volatile uint8_t *keyboard_out; | ||||
|     // Mouse out register | ||||
|     volatile uint8_t * mouse_out; | ||||
|     volatile uint8_t *mouse_out; | ||||
|     // Data in register | ||||
|     volatile uint8_t * data_in; | ||||
|     volatile uint8_t *data_in; | ||||
| }; | ||||
|  | ||||
| extern struct Kbc __code KBC; | ||||
| @@ -31,10 +31,10 @@ extern struct Kbc __code KBC; | ||||
| #define KBC_STS_IBF BIT(1) | ||||
| #define KBC_STS_CMD BIT(3) | ||||
|  | ||||
| uint8_t kbc_status(struct Kbc * kbc); | ||||
| uint8_t kbc_read(struct Kbc * kbc); | ||||
| bool kbc_keyboard(struct Kbc * kbc, uint8_t data, uint16_t timeout); | ||||
| bool kbc_mouse(struct Kbc * kbc, uint8_t data, uint16_t timeout); | ||||
| uint8_t kbc_status(struct Kbc *kbc); | ||||
| uint8_t kbc_read(struct Kbc *kbc); | ||||
| bool kbc_keyboard(struct Kbc *kbc, uint8_t data, uint16_t timeout); | ||||
| bool kbc_mouse(struct Kbc *kbc, uint8_t data, uint16_t timeout); | ||||
|  | ||||
| volatile uint8_t __xdata __at(0x1300) KBHICR; | ||||
| volatile uint8_t __xdata __at(0x1302) KBIRQR; | ||||
|   | ||||
| @@ -10,13 +10,13 @@ | ||||
|  | ||||
| struct Pmc { | ||||
|     // Status register | ||||
|     volatile uint8_t * status; | ||||
|     volatile uint8_t *status; | ||||
|     // Data out register | ||||
|     volatile uint8_t * data_out; | ||||
|     volatile uint8_t *data_out; | ||||
|     // Data in register | ||||
|     volatile uint8_t * data_in; | ||||
|     volatile uint8_t *data_in; | ||||
|     // Control register | ||||
|     volatile uint8_t * control; | ||||
|     volatile uint8_t *control; | ||||
| }; | ||||
|  | ||||
| extern struct Pmc __code PMC_1; | ||||
| @@ -29,10 +29,10 @@ extern struct Pmc __code PMC_5; | ||||
| #define PMC_STS_IBF BIT(1) | ||||
| #define PMC_STS_CMD BIT(3) | ||||
|  | ||||
| uint8_t pmc_status(struct Pmc * pmc); | ||||
| void pmc_set_status(struct Pmc * pmc, uint8_t status); | ||||
| uint8_t pmc_read(struct Pmc * pmc); | ||||
| void pmc_write(struct Pmc * pmc, uint8_t data); | ||||
| uint8_t pmc_status(struct Pmc *pmc); | ||||
| void pmc_set_status(struct Pmc *pmc, uint8_t status); | ||||
| uint8_t pmc_read(struct Pmc *pmc); | ||||
| void pmc_write(struct Pmc *pmc, uint8_t data); | ||||
|  | ||||
| volatile uint8_t __xdata __at(0x1500) PM1STS; | ||||
| volatile uint8_t __xdata __at(0x1501) PM1DO; | ||||
|   | ||||
| @@ -12,17 +12,17 @@ | ||||
| #define PSSTS_DONE BIT(3) | ||||
|  | ||||
| struct Ps2 { | ||||
|     volatile uint8_t * control; | ||||
|     volatile uint8_t * interrupt; | ||||
|     volatile uint8_t * status; | ||||
|     volatile uint8_t * data; | ||||
|     volatile uint8_t *control; | ||||
|     volatile uint8_t *interrupt; | ||||
|     volatile uint8_t *status; | ||||
|     volatile uint8_t *data; | ||||
| }; | ||||
|  | ||||
| extern struct Ps2 __code PS2_1; | ||||
| extern struct Ps2 __code PS2_2; | ||||
| extern struct Ps2 __code PS2_3; | ||||
|  | ||||
| void ps2_reset(struct Ps2 * ps2); | ||||
| void ps2_reset(struct Ps2 *ps2); | ||||
|  | ||||
| volatile uint8_t __xdata __at(0x1700) PSCTL1; | ||||
| volatile uint8_t __xdata __at(0x1701) PSCTL2; | ||||
|   | ||||
| @@ -17,13 +17,13 @@ volatile uint8_t __xdata __at(0x1045) SCAR1H; | ||||
| #endif | ||||
|  | ||||
| #if CONFIG_EC_ITE_IT8587E | ||||
|     #define SCARL SCAR1L | ||||
|     #define SCARM SCAR1M | ||||
|     #define SCARH SCAR1H | ||||
| #define SCARL SCAR1L | ||||
| #define SCARM SCAR1M | ||||
| #define SCARH SCAR1H | ||||
| #else | ||||
|     #define SCARL SCAR0L | ||||
|     #define SCARM SCAR0M | ||||
|     #define SCARH SCAR0H | ||||
| #define SCARL SCAR0L | ||||
| #define SCARM SCAR0M | ||||
| #define SCARH SCAR0H | ||||
| #endif | ||||
|  | ||||
| #endif // _EC_SCRATCH_H | ||||
|   | ||||
| @@ -12,32 +12,35 @@ struct Kbc __code KBC = { | ||||
|     .data_in = &KBHIDIR, | ||||
| }; | ||||
|  | ||||
| uint8_t kbc_status(struct Kbc * kbc) { | ||||
| uint8_t kbc_status(struct Kbc *kbc) { | ||||
|     return *(kbc->status); | ||||
| } | ||||
|  | ||||
| uint8_t kbc_read(struct Kbc * kbc) { | ||||
| uint8_t kbc_read(struct Kbc *kbc) { | ||||
|     return *(kbc->data_in); | ||||
| } | ||||
|  | ||||
| static bool kbc_wait(struct Kbc * kbc, uint16_t timeout) { | ||||
| static bool kbc_wait(struct Kbc *kbc, uint16_t timeout) { | ||||
|     while (*(kbc->status) & KBC_STS_OBF) { | ||||
|         if (timeout == 0) return false; | ||||
|         if (timeout == 0) | ||||
|             return false; | ||||
|         timeout -= 1; | ||||
|         delay_us(1); | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| bool kbc_keyboard(struct Kbc * kbc, uint8_t data, uint16_t timeout) { | ||||
|     if (!kbc_wait(kbc, timeout)) return false; | ||||
| bool kbc_keyboard(struct Kbc *kbc, uint8_t data, uint16_t timeout) { | ||||
|     if (!kbc_wait(kbc, timeout)) | ||||
|         return false; | ||||
|     *(kbc->status) &= ~0x20; | ||||
|     *(kbc->keyboard_out) = data; | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| bool kbc_mouse(struct Kbc * kbc, uint8_t data, uint16_t timeout) { | ||||
|     if (!kbc_wait(kbc, timeout)) return false; | ||||
| bool kbc_mouse(struct Kbc *kbc, uint8_t data, uint16_t timeout) { | ||||
|     if (!kbc_wait(kbc, timeout)) | ||||
|         return false; | ||||
|     *(kbc->status) |= 0x20; | ||||
|     *(kbc->mouse_out) = data; | ||||
|     return true; | ||||
|   | ||||
| @@ -17,18 +17,18 @@ struct Pmc __code PMC_3 = PMC(3); | ||||
| struct Pmc __code PMC_4 = PMC(4); | ||||
| struct Pmc __code PMC_5 = PMC(5); | ||||
|  | ||||
| uint8_t pmc_status(struct Pmc * pmc) { | ||||
| uint8_t pmc_status(struct Pmc *pmc) { | ||||
|     return *(pmc->status); | ||||
| } | ||||
|  | ||||
| void pmc_set_status(struct Pmc * pmc, uint8_t status) { | ||||
| void pmc_set_status(struct Pmc *pmc, uint8_t status) { | ||||
|     *(pmc->status) = status; | ||||
| } | ||||
|  | ||||
| uint8_t pmc_read(struct Pmc * pmc) { | ||||
| uint8_t pmc_read(struct Pmc *pmc) { | ||||
|     return *(pmc->data_in); | ||||
| } | ||||
|  | ||||
| void pmc_write(struct Pmc * pmc, uint8_t data) { | ||||
| void pmc_write(struct Pmc *pmc, uint8_t data) { | ||||
|     *(pmc->data_out) = data; | ||||
| } | ||||
|   | ||||
| @@ -15,7 +15,7 @@ struct Ps2 __code PS2_1 = PS2(1); | ||||
| struct Ps2 __code PS2_2 = PS2(2); | ||||
| struct Ps2 __code PS2_3 = PS2(3); | ||||
|  | ||||
| void ps2_reset(struct Ps2 * ps2) { | ||||
| void ps2_reset(struct Ps2 *ps2) { | ||||
|     // Reset interface to defaults | ||||
|     *(ps2->control) = 1; | ||||
|     // Clear status | ||||
|   | ||||
| @@ -72,11 +72,11 @@ | ||||
| // clang-format on | ||||
|  | ||||
| // Position of physical Esc key in the matrix | ||||
| #define MATRIX_ESC_INPUT    7 | ||||
| #define MATRIX_ESC_OUTPUT   7 | ||||
| #define MATRIX_ESC_INPUT 7 | ||||
| #define MATRIX_ESC_OUTPUT 7 | ||||
|  | ||||
| // Position of physical Fn key in the matrix | ||||
| #define MATRIX_FN_INPUT     0 | ||||
| #define MATRIX_FN_OUTPUT    6 | ||||
| #define MATRIX_FN_INPUT 0 | ||||
| #define MATRIX_FN_OUTPUT 6 | ||||
|  | ||||
| #endif // _BOARD_KEYMAP_H | ||||
|   | ||||
| @@ -43,11 +43,11 @@ | ||||
| // clang-format on | ||||
|  | ||||
| // Position of physical Esc key in the matrix | ||||
| #define MATRIX_ESC_INPUT    7 | ||||
| #define MATRIX_ESC_OUTPUT   7 | ||||
| #define MATRIX_ESC_INPUT 7 | ||||
| #define MATRIX_ESC_OUTPUT 7 | ||||
|  | ||||
| // Position of physical Fn key in the matrix | ||||
| #define MATRIX_FN_INPUT     0 | ||||
| #define MATRIX_FN_OUTPUT    6 | ||||
| #define MATRIX_FN_INPUT 0 | ||||
| #define MATRIX_FN_OUTPUT 6 | ||||
|  | ||||
| #endif // _BOARD_KEYMAP_H | ||||
|   | ||||
| @@ -15,10 +15,10 @@ | ||||
|  | ||||
| // International keys | ||||
| #ifndef KI1 | ||||
|     #define KI1 K_INT_1 | ||||
| #define KI1 K_INT_1 | ||||
| #endif | ||||
| #ifndef KI2 | ||||
|     #define KI2 K_INT_2 | ||||
| #define KI2 K_INT_2 | ||||
| #endif | ||||
|  | ||||
| // clang-format off | ||||
| @@ -53,11 +53,11 @@ | ||||
| // clang-format on | ||||
|  | ||||
| // Position of physical Esc key in the matrix | ||||
| #define MATRIX_ESC_INPUT    7 | ||||
| #define MATRIX_ESC_OUTPUT   7 | ||||
| #define MATRIX_ESC_INPUT 7 | ||||
| #define MATRIX_ESC_OUTPUT 7 | ||||
|  | ||||
| // Position of physical Fn key in the matrix | ||||
| #define MATRIX_FN_INPUT     3 | ||||
| #define MATRIX_FN_OUTPUT    17 | ||||
| #define MATRIX_FN_INPUT 3 | ||||
| #define MATRIX_FN_OUTPUT 17 | ||||
|  | ||||
| #endif // _BOARD_KEYMAP_H | ||||
|   | ||||
| @@ -47,11 +47,11 @@ | ||||
| // clang-format on | ||||
|  | ||||
| // Position of physical Esc key in the matrix | ||||
| #define MATRIX_ESC_INPUT    0 | ||||
| #define MATRIX_ESC_OUTPUT   6 | ||||
| #define MATRIX_ESC_INPUT 0 | ||||
| #define MATRIX_ESC_OUTPUT 6 | ||||
|  | ||||
| // Position of physical Fn key in the matrix | ||||
| #define MATRIX_FN_INPUT     0 | ||||
| #define MATRIX_FN_OUTPUT    4 | ||||
| #define MATRIX_FN_INPUT 0 | ||||
| #define MATRIX_FN_OUTPUT 4 | ||||
|  | ||||
| #endif // _BOARD_KEYMAP_H | ||||
|   | ||||
		Reference in New Issue
	
	Block a user