Merge pull request #1130 from stevew817/master

Silicon Labs - Cosmetic: apply mbed coding style to HAL
pull/1132/head
Martin Kojtal 2015-05-22 10:18:28 +01:00
commit 88d158e43b
31 changed files with 1455 additions and 1423 deletions

View File

@ -48,7 +48,7 @@ const PinMap PinMap_I2C_SCL[] = {
{PF1, I2C_0, 5}, {PF1, I2C_0, 5},
{PE13, I2C_0, 6}, {PE13, I2C_0, 6},
/* I2C1 */ /* I2C1 */
{PC5, I2C_1, 0}, {PC5, I2C_1, 0},
{PB12, I2C_1, 1}, {PB12, I2C_1, 1},
{PE1, I2C_1, 2}, {PE1, I2C_1, 2},
@ -68,7 +68,7 @@ const PinMap PinMap_I2C_SDA[] = {
{PF0, I2C_0, 5}, {PF0, I2C_0, 5},
{PE12, I2C_0, 6}, {PE12, I2C_0, 6},
/* I2C1 */ /* I2C1 */
{PC4, I2C_1, 0}, {PC4, I2C_1, 0},
{PB11, I2C_1, 1}, {PB11, I2C_1, 1},
{PE0, I2C_1, 2}, {PE0, I2C_1, 2},
@ -87,134 +87,134 @@ const PinMap PinMap_PWM[] = {
/*************SPI**************/ /*************SPI**************/
const PinMap PinMap_SPI_MOSI[] = { const PinMap PinMap_SPI_MOSI[] = {
/* USART0 */ /* USART0 */
{PE10, SPI_0, 0}, {PE10, SPI_0, 0},
{PE7, SPI_0, 1}, {PE7, SPI_0, 1},
{PC11, SPI_0, 2}, {PC11, SPI_0, 2},
{PC0, SPI_0, 5}, {PC0, SPI_0, 5},
/* USART1 */ /* USART1 */
{PD0, SPI_1, 1}, {PD0, SPI_1, 1},
{PD7, SPI_1, 2}, {PD7, SPI_1, 2},
/* USART2 */ /* USART2 */
{PC2, SPI_2, 0}, {PC2, SPI_2, 0},
{PB3, SPI_2, 1}, {PB3, SPI_2, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_SPI_MISO[] = { const PinMap PinMap_SPI_MISO[] = {
/* USART0 */ /* USART0 */
{PE11, SPI_0, 0}, {PE11, SPI_0, 0},
{PE6, SPI_0, 1}, {PE6, SPI_0, 1},
{PC10, SPI_0, 2}, {PC10, SPI_0, 2},
{PC1, SPI_0, 5}, {PC1, SPI_0, 5},
/* USART1 */ /* USART1 */
{PD1, SPI_1, 1}, {PD1, SPI_1, 1},
{PD6, SPI_1, 2}, {PD6, SPI_1, 2},
/* USART2 */ /* USART2 */
{PC3, SPI_2, 0}, {PC3, SPI_2, 0},
{PB4, SPI_2, 1}, {PB4, SPI_2, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_SPI_CLK[] = { const PinMap PinMap_SPI_CLK[] = {
/* USART0 */ /* USART0 */
{PE12, SPI_0, 0}, {PE12, SPI_0, 0},
{PE5, SPI_0, 1}, {PE5, SPI_0, 1},
{PC9, SPI_0, 2}, {PC9, SPI_0, 2},
{PB13, SPI_0, 5}, {PB13, SPI_0, 5},
/* USART1 */ /* USART1 */
{PD2, SPI_1, 1}, {PD2, SPI_1, 1},
{PF0, SPI_1, 2}, {PF0, SPI_1, 2},
/* USART2 */ /* USART2 */
{PC4, SPI_2, 0}, {PC4, SPI_2, 0},
{PB5, SPI_2, 1}, {PB5, SPI_2, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_SPI_CS[] = { const PinMap PinMap_SPI_CS[] = {
/* USART0 */ /* USART0 */
{PE13, SPI_0, 0}, {PE13, SPI_0, 0},
{PE4, SPI_0, 1}, {PE4, SPI_0, 1},
{PC8, SPI_0, 2}, {PC8, SPI_0, 2},
{PB14, SPI_0, 5}, {PB14, SPI_0, 5},
/* USART1 */ /* USART1 */
{PD3, SPI_1, 1}, {PD3, SPI_1, 1},
{PF1, SPI_1, 2}, {PF1, SPI_1, 2},
/* USART2 */ /* USART2 */
{PC5, SPI_2, 0}, {PC5, SPI_2, 0},
{PB6, SPI_2, 1}, {PB6, SPI_2, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
/************UART**************/ /************UART**************/
const PinMap PinMap_UART_TX[] = { const PinMap PinMap_UART_TX[] = {
/* UART0 */ /* UART0 */
{PF6, UART_0, 0}, {PF6, UART_0, 0},
{PE0, UART_0, 1}, {PE0, UART_0, 1},
/* UART1 */ /* UART1 */
{PF10, UART_1, 1}, {PF10, UART_1, 1},
{PB9, UART_1, 2}, {PB9, UART_1, 2},
{PE2, UART_1, 3}, {PE2, UART_1, 3},
/* USART0 */ /* USART0 */
{PE10, USART_0, 0}, {PE10, USART_0, 0},
{PE7, USART_0, 1}, {PE7, USART_0, 1},
{PC11, USART_0, 2}, {PC11, USART_0, 2},
{PE13, USART_0, 3}, {PE13, USART_0, 3},
{PB7, USART_0, 4}, {PB7, USART_0, 4},
/* USART1 */ /* USART1 */
{PC0, USART_1, 0}, {PC0, USART_1, 0},
{PD0, USART_1, 1}, {PD0, USART_1, 1},
{PD7, USART_1, 2}, {PD7, USART_1, 2},
/* USART2 */ /* USART2 */
{PC2, USART_2, 0}, {PC2, USART_2, 0},
{PB3, USART_2, 1}, {PB3, USART_2, 1},
/* LEUART0 */ /* LEUART0 */
{PD4, LEUART_0, 0}, {PD4, LEUART_0, 0},
{PB13, LEUART_0, 1}, {PB13, LEUART_0, 1},
{PE14, LEUART_0, 2}, {PE14, LEUART_0, 2},
{PF0, LEUART_0, 3}, {PF0, LEUART_0, 3},
{PF2, LEUART_0, 4}, {PF2, LEUART_0, 4},
/* LEUART1 */ /* LEUART1 */
{PC6, LEUART_1, 0}, {PC6, LEUART_1, 0},
{PA5, LEUART_1, 1}, {PA5, LEUART_1, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_UART_RX[] = { const PinMap PinMap_UART_RX[] = {
/* UART0 */ /* UART0 */
{PF7, UART_0, 0}, {PF7, UART_0, 0},
{PE1, UART_0, 1}, {PE1, UART_0, 1},
/* UART1 */ /* UART1 */
{PF11, UART_1, 1}, {PF11, UART_1, 1},
{PB10, UART_1, 2}, {PB10, UART_1, 2},
{PE3, UART_1, 3}, {PE3, UART_1, 3},
/* USART0 */ /* USART0 */
{PE11, USART_0, 0}, {PE11, USART_0, 0},
{PE6, USART_0, 1}, {PE6, USART_0, 1},
{PC10, USART_0, 2}, {PC10, USART_0, 2},
{PE12, USART_0, 3}, {PE12, USART_0, 3},
{PB8, USART_0, 4}, {PB8, USART_0, 4},
/* USART1 */ /* USART1 */
{PC1, USART_1, 0}, {PC1, USART_1, 0},
{PD1, USART_1, 1}, {PD1, USART_1, 1},
{PD6, USART_1, 2}, {PD6, USART_1, 2},
/* USART2 */ /* USART2 */
{PC3, USART_2, 0}, {PC3, USART_2, 0},
{PB4, USART_2, 1}, {PB4, USART_2, 1},
/* LEUART0 */ /* LEUART0 */
{PD5, LEUART_0, 0}, {PD5, LEUART_0, 0},
{PB14, LEUART_0, 1}, {PB14, LEUART_0, 1},
{PE15, LEUART_0, 2}, {PE15, LEUART_0, 2},
{PF1, LEUART_0, 3}, {PF1, LEUART_0, 3},
{PA0, LEUART_0, 4}, {PA0, LEUART_0, 4},
/* LEUART1 */ /* LEUART1 */
{PC7, LEUART_1, 0}, {PC7, LEUART_1, 0},
{PA6, LEUART_1, 1}, {PA6, LEUART_1, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };

View File

@ -24,7 +24,7 @@ extern "C" {
#endif #endif
typedef enum { typedef enum {
ADC_0 = ADC0_BASE ADC_0 = ADC0_BASE
} ADCName; } ADCName;
typedef enum { typedef enum {

View File

@ -60,109 +60,109 @@ const PinMap PinMap_PWM[] = {
/*************SPI**************/ /*************SPI**************/
const PinMap PinMap_SPI_MOSI[] = { const PinMap PinMap_SPI_MOSI[] = {
/* USART0 */ /* USART0 */
{PE10, SPI_0, 0}, {PE10, SPI_0, 0},
//{NC, SPI_0, 2}, /* SPI_0 loc2 is not bonded */ //{NC, SPI_0, 2}, /* SPI_0 loc2 is not bonded */
{PE13, SPI_0, 3}, {PE13, SPI_0, 3},
{PB7, SPI_0, 4}, {PB7, SPI_0, 4},
/* USART1 */ /* USART1 */
{PC0, SPI_1, 0}, {PC0, SPI_1, 0},
{PD7, SPI_1, 3}, {PD7, SPI_1, 3},
{PF2, SPI_1, 4}, {PF2, SPI_1, 4},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_SPI_MISO[] = { const PinMap PinMap_SPI_MISO[] = {
/* USART0 */ /* USART0 */
{PE11, SPI_0, 0}, {PE11, SPI_0, 0},
{PC10, SPI_0, 2}, {PC10, SPI_0, 2},
{PE12, SPI_0, 3}, {PE12, SPI_0, 3},
{PB8, SPI_0, 4}, {PB8, SPI_0, 4},
/* USART1 */ /* USART1 */
{PC1, SPI_1, 0}, {PC1, SPI_1, 0},
{PD6, SPI_1, 3}, {PD6, SPI_1, 3},
{PA0, SPI_1, 4}, {PA0, SPI_1, 4},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_SPI_CLK[] = { const PinMap PinMap_SPI_CLK[] = {
/* USART0 */ /* USART0 */
{PE12, SPI_0, 0}, {PE12, SPI_0, 0},
{PC9, SPI_0, 2}, {PC9, SPI_0, 2},
//{PC15, SPI_0, 3}, /* Conflict with SPI_0 loc4 */ //{PC15, SPI_0, 3}, /* Conflict with SPI_0 loc4 */
{PB13, SPI_0, 4}, {PB13, SPI_0, 4},
/* USART1 */ /* USART1 */
{PB7, SPI_1, 0}, {PB7, SPI_1, 0},
{PC15, SPI_1, 3}, {PC15, SPI_1, 3},
{PB11, SPI_1, 4}, {PB11, SPI_1, 4},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_SPI_CS[] = { const PinMap PinMap_SPI_CS[] = {
/* USART0 */ /* USART0 */
{PE13, SPI_0, 0}, {PE13, SPI_0, 0},
{PC8, SPI_0, 2}, {PC8, SPI_0, 2},
//{PC14, SPI_0, 3}, /* Conflict with SPI_1 loc3 */ //{PC14, SPI_0, 3}, /* Conflict with SPI_1 loc3 */
{PB14, SPI_0, 4}, {PB14, SPI_0, 4},
/* USART1 */ /* USART1 */
{PB8, SPI_1, 0}, {PB8, SPI_1, 0},
{PC14, SPI_1, 3}, {PC14, SPI_1, 3},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
/************UART**************/ /************UART**************/
const PinMap PinMap_UART_TX[] = { const PinMap PinMap_UART_TX[] = {
/* USART0 */ /* USART0 */
{PE10, USART_0, 0}, {PE10, USART_0, 0},
//{NC, USART_0, 2}, /* USART_0 loc2 is not bonded */ //{NC, USART_0, 2}, /* USART_0 loc2 is not bonded */
{PE13, USART_0, 3}, {PE13, USART_0, 3},
{PB7, USART_0, 4}, {PB7, USART_0, 4},
/* USART1 */ /* USART1 */
{PC0, USART_1, 0}, {PC0, USART_1, 0},
{PD7, USART_1, 3}, {PD7, USART_1, 3},
{PF2, USART_1, 4}, {PF2, USART_1, 4},
/* LEUART0 */ /* LEUART0 */
{PD4, LEUART_0, 0}, {PD4, LEUART_0, 0},
{PB13, LEUART_0, 1}, {PB13, LEUART_0, 1},
{PF0, LEUART_0, 3}, {PF0, LEUART_0, 3},
{PC14, LEUART_0, 5}, {PC14, LEUART_0, 5},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_UART_RX[] = { const PinMap PinMap_UART_RX[] = {
/* USART0 */ /* USART0 */
{PE11, USART_0, 0}, {PE11, USART_0, 0},
//{PC10, USART_0, 2}, //{PC10, USART_0, 2},
{PE12, USART_0, 3}, {PE12, USART_0, 3},
{PB8, USART_0, 4}, {PB8, USART_0, 4},
/* USART1 */ /* USART1 */
{PC1, USART_1, 0}, {PC1, USART_1, 0},
{PD6, USART_1, 3}, {PD6, USART_1, 3},
{PA0, USART_1, 4}, {PA0, USART_1, 4},
/* LEUART0 */ /* LEUART0 */
{PD5, LEUART_0, 0}, {PD5, LEUART_0, 0},
{PB14, LEUART_0, 1}, {PB14, LEUART_0, 1},
{PF1, LEUART_0, 3}, {PF1, LEUART_0, 3},
{PC15, LEUART_0, 5}, {PC15, LEUART_0, 5},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };

View File

@ -45,7 +45,7 @@
#define DEVICE_PWMOUT 1 #define DEVICE_PWMOUT 1
#define DEVICE_SLEEP 1 #define DEVICE_SLEEP 1
#define DEVICE_STDIO_MESSAGES 1 #define DEVICE_STDIO_MESSAGES 1
#define DEVICE_LOWPOWERTIMER 1 #define DEVICE_LOWPOWERTIMER 1

View File

@ -48,7 +48,7 @@ const PinMap PinMap_I2C_SCL[] = {
{PF1, I2C_0, 5}, {PF1, I2C_0, 5},
{PE13, I2C_0, 6}, {PE13, I2C_0, 6},
/* I2C1 */ /* I2C1 */
{PC5, I2C_1, 0}, {PC5, I2C_1, 0},
{PB12, I2C_1, 1}, {PB12, I2C_1, 1},
{PE1, I2C_1, 2}, {PE1, I2C_1, 2},
@ -68,7 +68,7 @@ const PinMap PinMap_I2C_SDA[] = {
{PF0, I2C_0, 5}, {PF0, I2C_0, 5},
{PE12, I2C_0, 6}, {PE12, I2C_0, 6},
/* I2C1 */ /* I2C1 */
{PC4, I2C_1, 0}, {PC4, I2C_1, 0},
{PB11, I2C_1, 1}, {PB11, I2C_1, 1},
{PE0, I2C_1, 2}, {PE0, I2C_1, 2},
@ -87,134 +87,134 @@ const PinMap PinMap_PWM[] = {
/*************SPI**************/ /*************SPI**************/
const PinMap PinMap_SPI_MOSI[] = { const PinMap PinMap_SPI_MOSI[] = {
/* USART0 */ /* USART0 */
{PE10, SPI_0, 0}, {PE10, SPI_0, 0},
{PE7, SPI_0, 1}, {PE7, SPI_0, 1},
{PC11, SPI_0, 2}, {PC11, SPI_0, 2},
{PC0, SPI_0, 5}, {PC0, SPI_0, 5},
/* USART1 */ /* USART1 */
{PD0, SPI_1, 1}, {PD0, SPI_1, 1},
{PD7, SPI_1, 2}, {PD7, SPI_1, 2},
/* USART2 */ /* USART2 */
{PC2, SPI_2, 0}, {PC2, SPI_2, 0},
{PB3, SPI_2, 1}, {PB3, SPI_2, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_SPI_MISO[] = { const PinMap PinMap_SPI_MISO[] = {
/* USART0 */ /* USART0 */
{PE11, SPI_0, 0}, {PE11, SPI_0, 0},
{PE6, SPI_0, 1}, {PE6, SPI_0, 1},
{PC10, SPI_0, 2}, {PC10, SPI_0, 2},
{PC1, SPI_0, 5}, {PC1, SPI_0, 5},
/* USART1 */ /* USART1 */
{PD1, SPI_1, 1}, {PD1, SPI_1, 1},
{PD6, SPI_1, 2}, {PD6, SPI_1, 2},
/* USART2 */ /* USART2 */
{PC3, SPI_2, 0}, {PC3, SPI_2, 0},
{PB4, SPI_2, 1}, {PB4, SPI_2, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_SPI_CLK[] = { const PinMap PinMap_SPI_CLK[] = {
/* USART0 */ /* USART0 */
{PE12, SPI_0, 0}, {PE12, SPI_0, 0},
{PE5, SPI_0, 1}, {PE5, SPI_0, 1},
{PC9, SPI_0, 2}, {PC9, SPI_0, 2},
{PB13, SPI_0, 5}, {PB13, SPI_0, 5},
/* USART1 */ /* USART1 */
{PD2, SPI_1, 1}, {PD2, SPI_1, 1},
{PF0, SPI_1, 2}, {PF0, SPI_1, 2},
/* USART2 */ /* USART2 */
{PC4, SPI_2, 0}, {PC4, SPI_2, 0},
{PB5, SPI_2, 1}, {PB5, SPI_2, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_SPI_CS[] = { const PinMap PinMap_SPI_CS[] = {
/* USART0 */ /* USART0 */
{PE13, SPI_0, 0}, {PE13, SPI_0, 0},
{PE4, SPI_0, 1}, {PE4, SPI_0, 1},
{PC8, SPI_0, 2}, {PC8, SPI_0, 2},
{PB14, SPI_0, 5}, {PB14, SPI_0, 5},
/* USART1 */ /* USART1 */
{PD3, SPI_1, 1}, {PD3, SPI_1, 1},
{PF1, SPI_1, 2}, {PF1, SPI_1, 2},
/* USART2 */ /* USART2 */
{PC5, SPI_2, 0}, {PC5, SPI_2, 0},
{PB6, SPI_2, 1}, {PB6, SPI_2, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
/************UART**************/ /************UART**************/
const PinMap PinMap_UART_TX[] = { const PinMap PinMap_UART_TX[] = {
/* UART0 */ /* UART0 */
{PF6, UART_0, 0}, {PF6, UART_0, 0},
{PE0, UART_0, 1}, {PE0, UART_0, 1},
/* UART1 */ /* UART1 */
{PF10, UART_1, 1}, {PF10, UART_1, 1},
{PB9, UART_1, 2}, {PB9, UART_1, 2},
{PE2, UART_1, 3}, {PE2, UART_1, 3},
/* USART0 */ /* USART0 */
{PE10, USART_0, 0}, {PE10, USART_0, 0},
{PE7, USART_0, 1}, {PE7, USART_0, 1},
{PC11, USART_0, 2}, {PC11, USART_0, 2},
{PE13, USART_0, 3}, {PE13, USART_0, 3},
{PB7, USART_0, 4}, {PB7, USART_0, 4},
/* USART1 */ /* USART1 */
{PC0, USART_1, 0}, {PC0, USART_1, 0},
{PD0, USART_1, 1}, {PD0, USART_1, 1},
{PD7, USART_1, 2}, {PD7, USART_1, 2},
/* USART2 */ /* USART2 */
{PC2, USART_2, 0}, {PC2, USART_2, 0},
{PB3, USART_2, 1}, {PB3, USART_2, 1},
/* LEUART0 */ /* LEUART0 */
{PD4, LEUART_0, 0}, {PD4, LEUART_0, 0},
{PB13, LEUART_0, 1}, {PB13, LEUART_0, 1},
{PE14, LEUART_0, 2}, {PE14, LEUART_0, 2},
{PF0, LEUART_0, 3}, {PF0, LEUART_0, 3},
{PF2, LEUART_0, 4}, {PF2, LEUART_0, 4},
/* LEUART1 */ /* LEUART1 */
{PC6, LEUART_1, 0}, {PC6, LEUART_1, 0},
{PA5, LEUART_1, 1}, {PA5, LEUART_1, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_UART_RX[] = { const PinMap PinMap_UART_RX[] = {
/* UART0 */ /* UART0 */
{PF7, UART_0, 0}, {PF7, UART_0, 0},
{PE1, UART_0, 1}, {PE1, UART_0, 1},
/* UART1 */ /* UART1 */
{PF11, UART_1, 1}, {PF11, UART_1, 1},
{PB10, UART_1, 2}, {PB10, UART_1, 2},
{PE3, UART_1, 3}, {PE3, UART_1, 3},
/* USART0 */ /* USART0 */
{PE11, USART_0, 0}, {PE11, USART_0, 0},
{PE6, USART_0, 1}, {PE6, USART_0, 1},
{PC10, USART_0, 2}, {PC10, USART_0, 2},
{PE12, USART_0, 3}, {PE12, USART_0, 3},
{PB8, USART_0, 4}, {PB8, USART_0, 4},
/* USART1 */ /* USART1 */
{PC1, USART_1, 0}, {PC1, USART_1, 0},
{PD1, USART_1, 1}, {PD1, USART_1, 1},
{PD6, USART_1, 2}, {PD6, USART_1, 2},
/* USART2 */ /* USART2 */
{PC3, USART_2, 0}, {PC3, USART_2, 0},
{PB4, USART_2, 1}, {PB4, USART_2, 1},
/* LEUART0 */ /* LEUART0 */
{PD5, LEUART_0, 0}, {PD5, LEUART_0, 0},
{PB14, LEUART_0, 1}, {PB14, LEUART_0, 1},
{PE15, LEUART_0, 2}, {PE15, LEUART_0, 2},
{PF1, LEUART_0, 3}, {PF1, LEUART_0, 3},
{PA0, LEUART_0, 4}, {PA0, LEUART_0, 4},
/* LEUART1 */ /* LEUART1 */
{PC7, LEUART_1, 0}, {PC7, LEUART_1, 0},
{PA6, LEUART_1, 1}, {PA6, LEUART_1, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#ifndef MBED_PERIPHERALPINS_H #ifndef MBED_PERIPHERALPINS_H
#define MBED_PERIPHERALPINS_H #define MBED_PERIPHERALPINS_H

View File

@ -92,8 +92,8 @@ typedef enum {
/* mbed modes: /* mbed modes:
* PullUp, PullDown, PullNone, OpenDrain * PullUp, PullDown, PullNone, OpenDrain
* *
* mbed default digital input mode: * mbed default digital input mode:
* PullDefault * PullDefault
* *
* mbed default digital output mode: * mbed default digital output mode:
* PullNone * PullNone

View File

@ -48,7 +48,7 @@ const PinMap PinMap_I2C_SCL[] = {
{PF1, I2C_0, 5}, {PF1, I2C_0, 5},
{PE13, I2C_0, 6}, {PE13, I2C_0, 6},
/* I2C1 */ /* I2C1 */
{PC5, I2C_1, 0}, {PC5, I2C_1, 0},
{PB12, I2C_1, 1}, {PB12, I2C_1, 1},
{PE1, I2C_1, 2}, {PE1, I2C_1, 2},
@ -68,7 +68,7 @@ const PinMap PinMap_I2C_SDA[] = {
{PF0, I2C_0, 5}, {PF0, I2C_0, 5},
{PE12, I2C_0, 6}, {PE12, I2C_0, 6},
/* I2C1 */ /* I2C1 */
{PC4, I2C_1, 0}, {PC4, I2C_1, 0},
{PB11, I2C_1, 1}, {PB11, I2C_1, 1},
{PE0, I2C_1, 2}, {PE0, I2C_1, 2},
@ -87,134 +87,134 @@ const PinMap PinMap_PWM[] = {
/*************SPI**************/ /*************SPI**************/
const PinMap PinMap_SPI_MOSI[] = { const PinMap PinMap_SPI_MOSI[] = {
/* USART0 */ /* USART0 */
{PE10, SPI_0, 0}, {PE10, SPI_0, 0},
{PE7, SPI_0, 1}, {PE7, SPI_0, 1},
{PC11, SPI_0, 2}, {PC11, SPI_0, 2},
{PC0, SPI_0, 5}, {PC0, SPI_0, 5},
/* USART1 */ /* USART1 */
{PD0, SPI_1, 1}, {PD0, SPI_1, 1},
{PD7, SPI_1, 2}, {PD7, SPI_1, 2},
/* USART2 */ /* USART2 */
{PC2, SPI_2, 0}, {PC2, SPI_2, 0},
{PB3, SPI_2, 1}, {PB3, SPI_2, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_SPI_MISO[] = { const PinMap PinMap_SPI_MISO[] = {
/* USART0 */ /* USART0 */
{PE11, SPI_0, 0}, {PE11, SPI_0, 0},
{PE6, SPI_0, 1}, {PE6, SPI_0, 1},
{PC10, SPI_0, 2}, {PC10, SPI_0, 2},
{PC1, SPI_0, 5}, {PC1, SPI_0, 5},
/* USART1 */ /* USART1 */
{PD1, SPI_1, 1}, {PD1, SPI_1, 1},
{PD6, SPI_1, 2}, {PD6, SPI_1, 2},
/* USART2 */ /* USART2 */
{PC3, SPI_2, 0}, {PC3, SPI_2, 0},
{PB4, SPI_2, 1}, {PB4, SPI_2, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_SPI_CLK[] = { const PinMap PinMap_SPI_CLK[] = {
/* USART0 */ /* USART0 */
{PE12, SPI_0, 0}, {PE12, SPI_0, 0},
{PE5, SPI_0, 1}, {PE5, SPI_0, 1},
{PC9, SPI_0, 2}, {PC9, SPI_0, 2},
{PB13, SPI_0, 5}, {PB13, SPI_0, 5},
/* USART1 */ /* USART1 */
{PD2, SPI_1, 1}, {PD2, SPI_1, 1},
{PF0, SPI_1, 2}, {PF0, SPI_1, 2},
/* USART2 */ /* USART2 */
{PC4, SPI_2, 0}, {PC4, SPI_2, 0},
{PB5, SPI_2, 1}, {PB5, SPI_2, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_SPI_CS[] = { const PinMap PinMap_SPI_CS[] = {
/* USART0 */ /* USART0 */
{PE13, SPI_0, 0}, {PE13, SPI_0, 0},
{PE4, SPI_0, 1}, {PE4, SPI_0, 1},
{PC8, SPI_0, 2}, {PC8, SPI_0, 2},
{PB14, SPI_0, 5}, {PB14, SPI_0, 5},
/* USART1 */ /* USART1 */
{PD3, SPI_1, 1}, {PD3, SPI_1, 1},
{PF1, SPI_1, 2}, {PF1, SPI_1, 2},
/* USART2 */ /* USART2 */
{PC5, SPI_2, 0}, {PC5, SPI_2, 0},
{PB6, SPI_2, 1}, {PB6, SPI_2, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
/************UART**************/ /************UART**************/
const PinMap PinMap_UART_TX[] = { const PinMap PinMap_UART_TX[] = {
/* UART0 */ /* UART0 */
{PF6, UART_0, 0}, {PF6, UART_0, 0},
{PE0, UART_0, 1}, {PE0, UART_0, 1},
/* UART1 */ /* UART1 */
{PF10, UART_1, 1}, {PF10, UART_1, 1},
{PB9, UART_1, 2}, {PB9, UART_1, 2},
{PE2, UART_1, 3}, {PE2, UART_1, 3},
/* USART0 */ /* USART0 */
{PE10, USART_0, 0}, {PE10, USART_0, 0},
{PE7, USART_0, 1}, {PE7, USART_0, 1},
{PC11, USART_0, 2}, {PC11, USART_0, 2},
{PE13, USART_0, 3}, {PE13, USART_0, 3},
{PB7, USART_0, 4}, {PB7, USART_0, 4},
/* USART1 */ /* USART1 */
{PC0, USART_1, 0}, {PC0, USART_1, 0},
{PD0, USART_1, 1}, {PD0, USART_1, 1},
{PD7, USART_1, 2}, {PD7, USART_1, 2},
/* USART2 */ /* USART2 */
{PC2, USART_2, 0}, {PC2, USART_2, 0},
{PB3, USART_2, 1}, {PB3, USART_2, 1},
/* LEUART0 */ /* LEUART0 */
{PD4, LEUART_0, 0}, {PD4, LEUART_0, 0},
{PB13, LEUART_0, 1}, {PB13, LEUART_0, 1},
{PE14, LEUART_0, 2}, {PE14, LEUART_0, 2},
{PF0, LEUART_0, 3}, {PF0, LEUART_0, 3},
{PF2, LEUART_0, 4}, {PF2, LEUART_0, 4},
/* LEUART1 */ /* LEUART1 */
{PC6, LEUART_1, 0}, {PC6, LEUART_1, 0},
{PA5, LEUART_1, 1}, {PA5, LEUART_1, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_UART_RX[] = { const PinMap PinMap_UART_RX[] = {
/* UART0 */ /* UART0 */
{PF7, UART_0, 0}, {PF7, UART_0, 0},
{PE1, UART_0, 1}, {PE1, UART_0, 1},
/* UART1 */ /* UART1 */
{PF11, UART_1, 1}, {PF11, UART_1, 1},
{PB10, UART_1, 2}, {PB10, UART_1, 2},
{PE3, UART_1, 3}, {PE3, UART_1, 3},
/* USART0 */ /* USART0 */
{PE11, USART_0, 0}, {PE11, USART_0, 0},
{PE6, USART_0, 1}, {PE6, USART_0, 1},
{PC10, USART_0, 2}, {PC10, USART_0, 2},
{PE12, USART_0, 3}, {PE12, USART_0, 3},
{PB8, USART_0, 4}, {PB8, USART_0, 4},
/* USART1 */ /* USART1 */
{PC1, USART_1, 0}, {PC1, USART_1, 0},
{PD1, USART_1, 1}, {PD1, USART_1, 1},
{PD6, USART_1, 2}, {PD6, USART_1, 2},
/* USART2 */ /* USART2 */
{PC3, USART_2, 0}, {PC3, USART_2, 0},
{PB4, USART_2, 1}, {PB4, USART_2, 1},
/* LEUART0 */ /* LEUART0 */
{PD5, LEUART_0, 0}, {PD5, LEUART_0, 0},
{PB14, LEUART_0, 1}, {PB14, LEUART_0, 1},
{PE15, LEUART_0, 2}, {PE15, LEUART_0, 2},
{PF1, LEUART_0, 3}, {PF1, LEUART_0, 3},
{PA0, LEUART_0, 4}, {PA0, LEUART_0, 4},
/* LEUART1 */ /* LEUART1 */
{PC7, LEUART_1, 0}, {PC7, LEUART_1, 0},
{PA6, LEUART_1, 1}, {PA6, LEUART_1, 1},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#ifndef MBED_PERIPHERALPINS_H #ifndef MBED_PERIPHERALPINS_H
#define MBED_PERIPHERALPINS_H #define MBED_PERIPHERALPINS_H

View File

@ -92,8 +92,8 @@ typedef enum {
/* mbed modes: /* mbed modes:
* PullUp, PullDown, PullNone, OpenDrain * PullUp, PullDown, PullNone, OpenDrain
* *
* mbed default digital input mode: * mbed default digital input mode:
* PullDefault * PullDefault
* *
* mbed default digital output mode: * mbed default digital output mode:
* PullNone * PullNone

View File

@ -24,7 +24,7 @@ extern "C" {
#endif #endif
typedef enum { typedef enum {
ADC_0 = ADC0_BASE ADC_0 = ADC0_BASE
} ADCName; } ADCName;
typedef enum { typedef enum {

View File

@ -60,60 +60,60 @@ const PinMap PinMap_PWM[] = {
/*************SPI**************/ /*************SPI**************/
const PinMap PinMap_SPI_MOSI[] = { const PinMap PinMap_SPI_MOSI[] = {
/* USART1 */ /* USART1 */
{PC0, SPI_1, 0}, {PC0, SPI_1, 0},
{PD7, SPI_1, 3}, {PD7, SPI_1, 3},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_SPI_MISO[] = { const PinMap PinMap_SPI_MISO[] = {
/* USART1 */ /* USART1 */
{PC1, SPI_1, 0}, {PC1, SPI_1, 0},
{PD6, SPI_1, 3}, {PD6, SPI_1, 3},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_SPI_CLK[] = { const PinMap PinMap_SPI_CLK[] = {
/* USART1 */ /* USART1 */
{PB7, SPI_1, 0}, {PB7, SPI_1, 0},
{PC15, SPI_1, 3}, {PC15, SPI_1, 3},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_SPI_CS[] = { const PinMap PinMap_SPI_CS[] = {
/* USART1 */ /* USART1 */
{PB8, SPI_1, 0}, {PB8, SPI_1, 0},
{PC14, SPI_1, 3}, {PC14, SPI_1, 3},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
/************UART**************/ /************UART**************/
const PinMap PinMap_UART_TX[] = { const PinMap PinMap_UART_TX[] = {
/* USART1 */ /* USART1 */
{PC0, USART_1, 0}, {PC0, USART_1, 0},
{PD7, USART_1, 3}, {PD7, USART_1, 3},
/* LEUART0 */ /* LEUART0 */
{PD4, LEUART_0, 0}, {PD4, LEUART_0, 0},
{PB13, LEUART_0, 1}, {PB13, LEUART_0, 1},
{PF0, LEUART_0, 3}, {PF0, LEUART_0, 3},
{PF2, LEUART_0, 4}, {PF2, LEUART_0, 4},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };
const PinMap PinMap_UART_RX[] = { const PinMap PinMap_UART_RX[] = {
/* USART1 */ /* USART1 */
{PC1, USART_1, 0}, {PC1, USART_1, 0},
{PD6, USART_1, 3}, {PD6, USART_1, 3},
/* LEUART0 */ /* LEUART0 */
{PD5, LEUART_0, 0}, {PD5, LEUART_0, 0},
{PB14, LEUART_0, 1}, {PB14, LEUART_0, 1},
{PF1, LEUART_0, 3}, {PF1, LEUART_0, 3},
{PA0, LEUART_0, 4}, {PA0, LEUART_0, 4},
/* Not connected */ /* Not connected */
{NC , NC , NC} {NC , NC , NC}
}; };

View File

@ -45,7 +45,7 @@
#define DEVICE_PWMOUT 1 #define DEVICE_PWMOUT 1
#define DEVICE_SLEEP 1 #define DEVICE_SLEEP 1
#define DEVICE_STDIO_MESSAGES 1 #define DEVICE_STDIO_MESSAGES 1
#define DEVICE_LOWPOWERTIMER 1 #define DEVICE_LOWPOWERTIMER 1

View File

@ -52,12 +52,12 @@ void analogin_init(analogin_t *obj, PinName pin)
if (!adc_initialized) { if (!adc_initialized) {
/* Turn on the clock */ /* Turn on the clock */
CMU_ClockEnable(cmuClock_ADC0, true); CMU_ClockEnable(cmuClock_ADC0, true);
/* Init with default settings */ /* Init with default settings */
ADC_Init_TypeDef init = ADC_INIT_DEFAULT; ADC_Init_TypeDef init = ADC_INIT_DEFAULT;
init.prescale = 4; init.prescale = 4;
ADC_Init(obj->adc, &init); ADC_Init(obj->adc, &init);
/* Init for single conversion use */ /* Init for single conversion use */
ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT; ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;
@ -67,7 +67,7 @@ void analogin_init(analogin_t *obj, PinName pin)
singleInit.acqTime = adcAcqTime32; singleInit.acqTime = adcAcqTime32;
ADC_InitSingle(obj->adc, &singleInit); ADC_InitSingle(obj->adc, &singleInit);
adc_initialized = 1; adc_initialized = 1;
} }
} }

View File

@ -37,22 +37,23 @@ void analogout_preinit(dac_t *obj, PinName pin)
{ {
obj->dac = (DAC_TypeDef *) pinmap_peripheral(pin, PinMap_DAC); obj->dac = (DAC_TypeDef *) pinmap_peripheral(pin, PinMap_DAC);
MBED_ASSERT((int) obj->dac != NC); MBED_ASSERT((int) obj->dac != NC);
obj->channel = pin_location(pin, PinMap_DAC); obj->channel = pin_location(pin, PinMap_DAC);
MBED_ASSERT((int) obj->channel != NC); MBED_ASSERT((int) obj->channel != NC);
} }
void analogout_init(dac_t *obj, PinName pin) { void analogout_init(dac_t *obj, PinName pin)
{
static uint8_t dac_initialized = 0; static uint8_t dac_initialized = 0;
/* init in-memory structure */ /* init in-memory structure */
analogout_preinit(obj, pin); analogout_preinit(obj, pin);
if (!dac_initialized) { if (!dac_initialized) {
/* Initialize the DAC. Will disable both DAC channels, so should only be done once */ /* Initialize the DAC. Will disable both DAC channels, so should only be done once */
/* Use default settings */ /* Use default settings */
CMU_ClockEnable(cmuClock_DAC0, true); CMU_ClockEnable(cmuClock_DAC0, true);
DAC_Init_TypeDef init = DAC_INIT_DEFAULT; DAC_Init_TypeDef init = DAC_INIT_DEFAULT;
/* Calculate the DAC clock prescaler value that will result in a DAC clock /* Calculate the DAC clock prescaler value that will result in a DAC clock
@ -83,7 +84,8 @@ void analogout_pins_enable(dac_t *obj, uint8_t enable)
//not avail for EFM32 //not avail for EFM32
} }
static inline void dac_write(dac_t *obj, int value) { static inline void dac_write(dac_t *obj, int value)
{
switch (obj->channel) { switch (obj->channel) {
case 0: case 0:
obj->dac->CH0DATA = value; obj->dac->CH0DATA = value;
@ -94,7 +96,8 @@ static inline void dac_write(dac_t *obj, int value) {
} }
} }
static inline int dac_read(dac_t *obj) { static inline int dac_read(dac_t *obj)
{
switch (obj->channel) { switch (obj->channel) {
case 0: case 0:
return obj->dac->CH0DATA; return obj->dac->CH0DATA;
@ -109,23 +112,27 @@ static inline int dac_read(dac_t *obj) {
} }
} }
void analogout_write(dac_t *obj, float value) { void analogout_write(dac_t *obj, float value)
{
/* We multiply the float value with 0xFFF because the DAC has 12-bit resolution. /* We multiply the float value with 0xFFF because the DAC has 12-bit resolution.
* Ie. accepts values between 0 and 0xFFF (4096). */ * Ie. accepts values between 0 and 0xFFF (4096). */
dac_write(obj, value*0xFFF); dac_write(obj, value*0xFFF);
} }
void analogout_write_u16(dac_t *obj, uint16_t value) { void analogout_write_u16(dac_t *obj, uint16_t value)
{
/* The DAC has 12 bit resolution, so we remove the 4 least significant bits */ /* The DAC has 12 bit resolution, so we remove the 4 least significant bits */
dac_write(obj, value >> 4); dac_write(obj, value >> 4);
} }
float analogout_read(dac_t *obj) { float analogout_read(dac_t *obj)
{
/* dac_read returns a number between 0 and 0xFFF. Division gives us a float between 0 and 1 */ /* dac_read returns a number between 0 and 0xFFF. Division gives us a float between 0 and 1 */
return dac_read(obj)/(float)0xFFF; return dac_read(obj)/(float)0xFFF;
} }
uint16_t analogout_read_u16(dac_t *obj) { uint16_t analogout_read_u16(dac_t *obj)
{
/* dac_read returns a number with 12 significant digits, /* dac_read returns a number with 12 significant digits,
* so we shift in 0s from right to make it a 16 bit number */ * so we shift in 0s from right to make it a 16 bit number */
return dac_read(obj) << 4; return dac_read(obj) << 4;

View File

@ -39,55 +39,51 @@ bool enabled = false;
void dma_init(void) void dma_init(void)
{ {
if (enabled) return; if (enabled) return;
DMA_Init_TypeDef dmaInit; DMA_Init_TypeDef dmaInit;
CMU_ClockEnable(cmuClock_DMA, true); CMU_ClockEnable(cmuClock_DMA, true);
CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_HFPER, true);
/* Configure general DMA issues */ /* Configure general DMA issues */
dmaInit.hprot = 0; dmaInit.hprot = 0;
dmaInit.controlBlock = dmaControlBlock; dmaInit.controlBlock = dmaControlBlock;
DMA_Init(&dmaInit); DMA_Init(&dmaInit);
enabled = true; enabled = true;
} }
int dma_channel_allocate(uint32_t capabilities) int dma_channel_allocate(uint32_t capabilities)
{ {
int i; int i;
// Check if 2d copy is required // Check if 2d copy is required
if (DMA_CAP_2DCOPY & capabilities) if (DMA_CAP_2DCOPY & capabilities) {
{ if (channels & 1) {
if (channels & 1) // Channel already in use
{ return DMA_ERROR_OUT_OF_CHANNELS;
// Channel already in use } else {
return DMA_ERROR_OUT_OF_CHANNELS; channels |= 1 << 0;
} else { return 0;
channels |= 1 << 0; }
return 0;
} }
} for (i = 1; i < DMA_CHAN_COUNT; i++) {
for (i = 1; i < DMA_CHAN_COUNT; i++) if ((channels & (1 << i)) == 0) {
{ // Channel available
if ((channels & (1 << i)) == 0) channels |= 1 << i;
{ return i;
// Channel available }
channels |= 1 << i;
return i;
} }
} // Check if channel 0 is available
// Check if channel 0 is available if ((channels & 1 ) == 0) {
if ((channels & 1 ) == 0) { channels |= 1 << 0;
channels |= 1 << 0; return 0;
return 0; }
} // Couldn't find a channel.
// Couldn't find a channel. return DMA_ERROR_OUT_OF_CHANNELS;
return DMA_ERROR_OUT_OF_CHANNELS;
} }
int dma_channel_free(int channelid) int dma_channel_free(int channelid)
{ {
channels &= ~(1 << channelid); channels &= ~(1 << channelid);
return 0; return 0;
} }

View File

@ -46,9 +46,9 @@ extern "C" {
#endif #endif
typedef struct { typedef struct {
DMAUsage dmaUsageState; DMAUsage dmaUsageState;
int dmaChannel; int dmaChannel;
DMA_CB_TypeDef dmaCallback; DMA_CB_TypeDef dmaCallback;
} DMA_OPTIONS_t; } DMA_OPTIONS_t;
typedef void (*DMACallback)(void); typedef void (*DMACallback)(void);

View File

@ -59,7 +59,7 @@ void gpio_mode(gpio_t *obj, PinMode mode)
{ {
obj->mode = mode; // Update object obj->mode = mode; // Update object
pin_mode(obj->pin, mode); // Update register pin_mode(obj->pin, mode); // Update register
//Handle pullup for input //Handle pullup for input
if(mode == InputPullUp) { if(mode == InputPullUp) {
//Set DOUT //Set DOUT

View File

@ -37,9 +37,9 @@
#define GPIOINT_MASK2IDX(mask) (countTrailingZeros(mask)) #define GPIOINT_MASK2IDX(mask) (countTrailingZeros(mask))
__STATIC_INLINE uint32_t countTrailingZeros(uint32_t mask) __STATIC_INLINE uint32_t countTrailingZeros(uint32_t mask)
{ {
uint32_t zeros; uint32_t zeros;
for(zeros=0; (zeros<32) && (0 == (mask&0x1)); zeros++, mask>>=1); for(zeros=0; (zeros<32) && (0 == (mask&0x1)); zeros++, mask>>=1);
return zeros; return zeros;
} }
#else #else
#error Unsupported architecture. #error Unsupported architecture.
@ -85,8 +85,8 @@ void gpio_irq_preinit(gpio_irq_t *obj, PinName pin)
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
{ {
/* Init pins */ /* Init pins */
gpio_irq_preinit(obj, pin); gpio_irq_preinit(obj, pin);
/* Initialize GPIO interrupt dispatcher */ /* Initialize GPIO interrupt dispatcher */
NVIC_ClearPendingIRQ(GPIO_ODD_IRQn); NVIC_ClearPendingIRQ(GPIO_ODD_IRQn);
NVIC_EnableIRQ(GPIO_ODD_IRQn); NVIC_EnableIRQ(GPIO_ODD_IRQn);
@ -128,19 +128,19 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
/* Disable, set config and enable */ /* Disable, set config and enable */
gpio_irq_disable(obj); gpio_irq_disable(obj);
bool was_disabled = false; bool was_disabled = false;
if(GPIO->IEN == 0) was_disabled = true; if(GPIO->IEN == 0) was_disabled = true;
GPIO_IntConfig(obj->port, obj->pin, obj->risingEdge, obj->fallingEdge, obj->risingEdge || obj->fallingEdge); GPIO_IntConfig(obj->port, obj->pin, obj->risingEdge, obj->fallingEdge, obj->risingEdge || obj->fallingEdge);
if ((GPIO->IEN != 0) && (obj->risingEdge || obj->fallingEdge) && was_disabled) { if ((GPIO->IEN != 0) && (obj->risingEdge || obj->fallingEdge) && was_disabled) {
blockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE); blockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE);
} }
} }
inline void gpio_irq_enable(gpio_irq_t *obj) inline void gpio_irq_enable(gpio_irq_t *obj)
{ {
if(GPIO->IEN == 0) blockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE); if(GPIO->IEN == 0) blockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE);
GPIO_IntEnable(1 << obj->pin); // pin mask for pins to enable GPIO_IntEnable(1 << obj->pin); // pin mask for pins to enable
} }
@ -165,19 +165,18 @@ inline void gpio_irq_disable(gpio_irq_t *obj)
******************************************************************************/ ******************************************************************************/
static void GPIOINT_IRQDispatcher(uint32_t iflags) static void GPIOINT_IRQDispatcher(uint32_t iflags)
{ {
uint32_t irqIdx; uint32_t irqIdx;
/* check for all flags set in IF register */ /* check for all flags set in IF register */
while(iflags) while(iflags) {
{ irqIdx = GPIOINT_MASK2IDX(iflags);
irqIdx = GPIOINT_MASK2IDX(iflags);
/* clear flag*/ /* clear flag*/
iflags &= ~(1 << irqIdx); iflags &= ~(1 << irqIdx);
/* call user callback */ /* call user callback */
handle_interrupt_in(irqIdx); handle_interrupt_in(irqIdx);
} }
} }
/***************************************************************************//** /***************************************************************************//**
@ -188,15 +187,15 @@ static void GPIOINT_IRQDispatcher(uint32_t iflags)
******************************************************************************/ ******************************************************************************/
void GPIO_EVEN_IRQHandler(void) void GPIO_EVEN_IRQHandler(void)
{ {
uint32_t iflags; uint32_t iflags;
/* Get all even interrupts. */ /* Get all even interrupts. */
iflags = GPIO_IntGetEnabled() & 0x00005555; iflags = GPIO_IntGetEnabled() & 0x00005555;
/* Clean only even interrupts. */ /* Clean only even interrupts. */
GPIO_IntClear(iflags); GPIO_IntClear(iflags);
GPIOINT_IRQDispatcher(iflags); GPIOINT_IRQDispatcher(iflags);
} }
@ -208,15 +207,15 @@ void GPIO_EVEN_IRQHandler(void)
******************************************************************************/ ******************************************************************************/
void GPIO_ODD_IRQHandler(void) void GPIO_ODD_IRQHandler(void)
{ {
uint32_t iflags; uint32_t iflags;
/* Get all odd interrupts. */ /* Get all odd interrupts. */
iflags = GPIO_IntGetEnabled() & 0x0000AAAA; iflags = GPIO_IntGetEnabled() & 0x0000AAAA;
/* Clean only even interrupts. */ /* Clean only even interrupts. */
GPIO_IntClear(iflags); GPIO_IntClear(iflags);
GPIOINT_IRQDispatcher(iflags); GPIOINT_IRQDispatcher(iflags);
} }
#endif #endif

View File

@ -49,7 +49,8 @@ static inline int gpio_read(gpio_t *obj)
} }
} }
static inline int gpio_is_connected(const gpio_t *obj) { static inline int gpio_is_connected(const gpio_t *obj)
{
return obj->pin != (PinName)NC; return obj->pin != (PinName)NC;
} }

View File

@ -75,7 +75,7 @@ static CMU_Clock_TypeDef i2c_get_clock(i2c_t *obj)
#endif #endif
#ifdef I2C1 #ifdef I2C1
case I2C_1: case I2C_1:
clock = cmuClock_I2C1; clock = cmuClock_I2C1;
break; break;
#endif #endif
default: default:
@ -104,10 +104,10 @@ void i2c_preinit(i2c_t *obj, PinName sda, PinName scl)
void i2c_init(i2c_t *obj, PinName sda, PinName scl) void i2c_init(i2c_t *obj, PinName sda, PinName scl)
{ {
/* Assign mbed pins */ /* Assign mbed pins */
i2c_preinit(obj, sda, scl); i2c_preinit(obj, sda, scl);
/* Enable clock for the peripheral */ /* Enable clock for the peripheral */
CMU_ClockEnable(i2c_get_clock(obj), true); CMU_ClockEnable(i2c_get_clock(obj), true);
/* Initializing the I2C */ /* Initializing the I2C */
/* Using default settings */ /* Using default settings */
@ -137,7 +137,7 @@ void i2c_enable(i2c_t *obj, uint8_t enable)
if (obj->i2c.i2c->STATE & I2C_STATE_BUSY) { if (obj->i2c.i2c->STATE & I2C_STATE_BUSY) {
obj->i2c.i2c->CMD = I2C_CMD_ABORT; obj->i2c.i2c->CMD = I2C_CMD_ABORT;
} }
} }
} }
@ -222,14 +222,14 @@ int i2c_stop(i2c_t *obj)
/* Returns number of bytes read */ /* Returns number of bytes read */
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
{ {
int retval; int retval;
i2c_start(obj); i2c_start(obj);
retval = i2c_byte_write(obj, (address | 1)); retval = i2c_byte_write(obj, (address | 1));
if ((!retval) || (length == 0)) { //Write address with W flag (last bit 1) if ((!retval) || (length == 0)) { //Write address with W flag (last bit 1)
obj->i2c.i2c->CMD = I2C_CMD_STOP | I2C_CMD_ABORT; obj->i2c.i2c->CMD = I2C_CMD_STOP | I2C_CMD_ABORT;
while(obj->i2c.i2c->STATE & I2C_STATE_BUSY); // Wait until the bus is done while(obj->i2c.i2c->STATE & I2C_STATE_BUSY); // Wait until the bus is done
return (retval == 0 ? I2C_ERROR_NO_SLAVE : 0); //NACK or error when writing adress. Return 0 as 0 bytes were read return (retval == 0 ? I2C_ERROR_NO_SLAVE : 0); //NACK or error when writing adress. Return 0 as 0 bytes were read
} }
int i = 0; int i = 0;
@ -344,10 +344,10 @@ int block_and_wait_for_ack(I2C_TypeDef *i2c)
void i2c_slave_mode(i2c_t *obj, int enable_slave) void i2c_slave_mode(i2c_t *obj, int enable_slave)
{ {
if(enable_slave){ if(enable_slave) {
obj->i2c.i2c->CTRL |= _I2C_CTRL_SLAVE_MASK; obj->i2c.i2c->CTRL |= _I2C_CTRL_SLAVE_MASK;
obj->i2c.i2c->CTRL |= _I2C_CTRL_AUTOACK_MASK; //Slave implementation assumes auto acking obj->i2c.i2c->CTRL |= _I2C_CTRL_AUTOACK_MASK; //Slave implementation assumes auto acking
}else{ } else {
obj->i2c.i2c->CTRL &= ~_I2C_CTRL_SLAVE_MASK; obj->i2c.i2c->CTRL &= ~_I2C_CTRL_SLAVE_MASK;
obj->i2c.i2c->CTRL &= ~_I2C_CTRL_AUTOACK_MASK; //Master implementation ACKs manually obj->i2c.i2c->CTRL &= ~_I2C_CTRL_AUTOACK_MASK; //Master implementation ACKs manually
} }
@ -356,19 +356,19 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave)
int i2c_slave_receive(i2c_t *obj) int i2c_slave_receive(i2c_t *obj)
{ {
if(obj->i2c.i2c->IF & I2C_IF_ADDR){ if(obj->i2c.i2c->IF & I2C_IF_ADDR) {
obj->i2c.i2c->IFC = I2C_IF_ADDR; //Clear interrupt obj->i2c.i2c->IFC = I2C_IF_ADDR; //Clear interrupt
/*0x00 is the address for general write. /*0x00 is the address for general write.
The address the master wrote is in RXDATA now The address the master wrote is in RXDATA now
and reading it also frees the buffer for the next and reading it also frees the buffer for the next
write which can then be acked. */ write which can then be acked. */
if(obj->i2c.i2c->RXDATA == 0x00){ if(obj->i2c.i2c->RXDATA == 0x00) {
return WriteGeneral; //Read the address; return WriteGeneral; //Read the address;
} }
if(obj->i2c.i2c->STATE & I2C_STATE_TRANSMITTER){ if(obj->i2c.i2c->STATE & I2C_STATE_TRANSMITTER) {
return ReadAddressed; return ReadAddressed;
}else{ } else {
return WriteAddressed; return WriteAddressed;
} }
} }
@ -383,7 +383,7 @@ int i2c_slave_read(i2c_t *obj, char *data, int length)
for (count = 0; count < length; count++) { for (count = 0; count < length; count++) {
data[count] = i2c_byte_read(obj, 0); data[count] = i2c_byte_read(obj, 0);
} }
return count; return count;
@ -426,128 +426,131 @@ void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
* @param handler The I2C IRQ handler to be set * @param handler The I2C IRQ handler to be set
* @param hint DMA hint usage * @param hint DMA hint usage
*/ */
void i2c_transfer_asynch(i2c_t *obj, void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint) { void i2c_transfer_asynch(i2c_t *obj, void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint)
I2C_TransferReturn_TypeDef retval; {
if(i2c_active(obj)) return; I2C_TransferReturn_TypeDef retval;
if(i2c_active(obj)) return;
if((tx_length == 0) && (rx_length == 0)) return; if((tx_length == 0) && (rx_length == 0)) return;
// For now, we are assuming a solely interrupt-driven implementation. // For now, we are assuming a solely interrupt-driven implementation.
// Store transfer config // Store transfer config
obj->i2c.xfer.addr = address; obj->i2c.xfer.addr = address;
// Some combination of tx_length and rx_length will tell us what to do // Some combination of tx_length and rx_length will tell us what to do
if((tx_length > 0) && (rx_length == 0)) { if((tx_length > 0) && (rx_length == 0)) {
obj->i2c.xfer.flags = I2C_FLAG_WRITE; obj->i2c.xfer.flags = I2C_FLAG_WRITE;
//Store buffer info //Store buffer info
obj->i2c.xfer.buf[0].data = tx; obj->i2c.xfer.buf[0].data = tx;
obj->i2c.xfer.buf[0].len = (uint16_t) tx_length; obj->i2c.xfer.buf[0].len = (uint16_t) tx_length;
} else if ((tx_length == 0) && (rx_length > 0)) { } else if ((tx_length == 0) && (rx_length > 0)) {
obj->i2c.xfer.flags = I2C_FLAG_READ; obj->i2c.xfer.flags = I2C_FLAG_READ;
//Store buffer info //Store buffer info
obj->i2c.xfer.buf[0].data = rx; obj->i2c.xfer.buf[0].data = rx;
obj->i2c.xfer.buf[0].len = (uint16_t) rx_length; obj->i2c.xfer.buf[0].len = (uint16_t) rx_length;
} else if ((tx_length > 0) && (rx_length > 0)) { } else if ((tx_length > 0) && (rx_length > 0)) {
obj->i2c.xfer.flags = I2C_FLAG_WRITE_READ; obj->i2c.xfer.flags = I2C_FLAG_WRITE_READ;
//Store buffer info //Store buffer info
obj->i2c.xfer.buf[0].data = tx; obj->i2c.xfer.buf[0].data = tx;
obj->i2c.xfer.buf[0].len = (uint16_t) tx_length; obj->i2c.xfer.buf[0].len = (uint16_t) tx_length;
obj->i2c.xfer.buf[1].data = rx; obj->i2c.xfer.buf[1].data = rx;
obj->i2c.xfer.buf[1].len = (uint16_t) rx_length; obj->i2c.xfer.buf[1].len = (uint16_t) rx_length;
} }
if(address > 255) obj->i2c.xfer.flags |= I2C_FLAG_10BIT_ADDR; if(address > 255) obj->i2c.xfer.flags |= I2C_FLAG_10BIT_ADDR;
// Store event flags // Store event flags
obj->i2c.events = event; obj->i2c.events = event;
// Enable interrupt // Enable interrupt
i2c_enable_interrupt(obj, handler, true); i2c_enable_interrupt(obj, handler, true);
// Kick off the transfer // Kick off the transfer
retval = I2C_TransferInit(obj->i2c.i2c, &(obj->i2c.xfer)); retval = I2C_TransferInit(obj->i2c.i2c, &(obj->i2c.xfer));
if(retval == i2cTransferInProgress) { if(retval == i2cTransferInProgress) {
blockSleepMode(EM1); blockSleepMode(EM1);
} } else {
else { // something happened, and the transfer did not go through
// something happened, and the transfer did not go through // So, we need to clean up
// So, we need to clean up
// Disable interrupt // Disable interrupt
i2c_enable_interrupt(obj, 0, false); i2c_enable_interrupt(obj, 0, false);
// Block until free // Block until free
while(i2c_active(obj)); while(i2c_active(obj));
} }
} }
/** The asynchronous IRQ handler /** The asynchronous IRQ handler
* @param obj The I2C object which holds the transfer information * @param obj The I2C object which holds the transfer information
* @return Returns event flags if a transfer termination condition was met or 0 otherwise. * @return Returns event flags if a transfer termination condition was met or 0 otherwise.
*/ */
uint32_t i2c_irq_handler_asynch(i2c_t *obj) { uint32_t i2c_irq_handler_asynch(i2c_t *obj)
{
// For now, we are assuming a solely interrupt-driven implementation. // For now, we are assuming a solely interrupt-driven implementation.
I2C_TransferReturn_TypeDef status = I2C_Transfer(obj->i2c.i2c); I2C_TransferReturn_TypeDef status = I2C_Transfer(obj->i2c.i2c);
switch(status) { switch(status) {
case i2cTransferInProgress: case i2cTransferInProgress:
// Still busy transferring, so let it. // Still busy transferring, so let it.
return 0; return 0;
case i2cTransferDone: case i2cTransferDone:
// Transfer has completed // Transfer has completed
// Disable interrupt // Disable interrupt
i2c_enable_interrupt(obj, 0, false); i2c_enable_interrupt(obj, 0, false);
unblockSleepMode(EM1); unblockSleepMode(EM1);
return I2C_EVENT_TRANSFER_COMPLETE & obj->i2c.events; return I2C_EVENT_TRANSFER_COMPLETE & obj->i2c.events;
case i2cTransferNack: case i2cTransferNack:
// A NACK has been received while an ACK was expected. This is usually because the slave did not respond to the address. // A NACK has been received while an ACK was expected. This is usually because the slave did not respond to the address.
// Disable interrupt // Disable interrupt
i2c_enable_interrupt(obj, 0, false); i2c_enable_interrupt(obj, 0, false);
unblockSleepMode(EM1); unblockSleepMode(EM1);
return I2C_EVENT_ERROR_NO_SLAVE & obj->i2c.events; return I2C_EVENT_ERROR_NO_SLAVE & obj->i2c.events;
default: default:
// An error situation has arisen. // An error situation has arisen.
// Disable interrupt // Disable interrupt
i2c_enable_interrupt(obj, 0, false); i2c_enable_interrupt(obj, 0, false);
unblockSleepMode(EM1); unblockSleepMode(EM1);
// return error // return error
return I2C_EVENT_ERROR & obj->i2c.events; return I2C_EVENT_ERROR & obj->i2c.events;
} }
} }
/** Attempts to determine if I2C peripheral is already in use. /** Attempts to determine if I2C peripheral is already in use.
* @param obj The I2C object * @param obj The I2C object
* @return non-zero if the I2C module is active or zero if it is not * @return non-zero if the I2C module is active or zero if it is not
*/ */
uint8_t i2c_active(i2c_t *obj) { uint8_t i2c_active(i2c_t *obj)
return (obj->i2c.i2c->STATE & I2C_STATE_BUSY); {
return (obj->i2c.i2c->STATE & I2C_STATE_BUSY);
} }
/** Abort ongoing asynchronous transaction. /** Abort ongoing asynchronous transaction.
* @param obj The I2C object * @param obj The I2C object
*/ */
void i2c_abort_asynch(i2c_t *obj) { void i2c_abort_asynch(i2c_t *obj)
// Do not deactivate I2C twice {
if (!i2c_active(obj)) return; // Do not deactivate I2C twice
if (!i2c_active(obj)) return;
// Disable interrupt // Disable interrupt
i2c_enable_interrupt(obj, 0, false); i2c_enable_interrupt(obj, 0, false);
// Abort // Abort
obj->i2c.i2c->CMD = I2C_CMD_STOP | I2C_CMD_ABORT; obj->i2c.i2c->CMD = I2C_CMD_STOP | I2C_CMD_ABORT;
// Block until free // Block until free
while(i2c_active(obj)); while(i2c_active(obj));
unblockSleepMode(EM1); unblockSleepMode(EM1);
} }
#endif //DEVICE_I2C ASYNCH #endif //DEVICE_I2C ASYNCH

View File

@ -27,53 +27,57 @@ void lp_ticker_init()
rtc_set_comp0_handler((uint32_t)lp_ticker_irq_handler); rtc_set_comp0_handler((uint32_t)lp_ticker_irq_handler);
} }
void lp_ticker_set_interrupt(timestamp_t timestamp) { void lp_ticker_set_interrupt(timestamp_t timestamp)
uint64_t timestamp_ticks; {
uint64_t timestamp_ticks;
uint64_t current_ticks = RTC_CounterGet(); uint64_t current_ticks = RTC_CounterGet();
timestamp_t current_time = ((uint64_t)(current_ticks * 1000000) / (LOW_ENERGY_CLOCK_FREQUENCY / RTC_CLOCKDIV_INT)); timestamp_t current_time = ((uint64_t)(current_ticks * 1000000) / (LOW_ENERGY_CLOCK_FREQUENCY / RTC_CLOCKDIV_INT));
/* calculate offset value */ /* calculate offset value */
timestamp_t offset = timestamp - current_time; timestamp_t offset = timestamp - current_time;
if(offset > 0xEFFFFFFF) offset = 100; if(offset > 0xEFFFFFFF) offset = 100;
/* map offset to RTC value */ /* map offset to RTC value */
// ticks = offset * RTC frequency div 1000000 // ticks = offset * RTC frequency div 1000000
timestamp_ticks = ((uint64_t)offset * (LOW_ENERGY_CLOCK_FREQUENCY / RTC_CLOCKDIV_INT)) / 1000000; timestamp_ticks = ((uint64_t)offset * (LOW_ENERGY_CLOCK_FREQUENCY / RTC_CLOCKDIV_INT)) / 1000000;
timestamp_ticks += current_ticks; timestamp_ticks += current_ticks;
/* RTC has 24 bit resolution */ /* RTC has 24 bit resolution */
timestamp_ticks &= 0xFFFFFF; timestamp_ticks &= 0xFFFFFF;
/* check for RTC limitation */ /* check for RTC limitation */
if((timestamp_ticks - RTC_CounterGet()) >= 0x800000) timestamp_ticks = RTC_CounterGet() + 2; if((timestamp_ticks - RTC_CounterGet()) >= 0x800000) timestamp_ticks = RTC_CounterGet() + 2;
/* Set callback */ /* Set callback */
RTC_FreezeEnable(true); RTC_FreezeEnable(true);
RTC_CompareSet(0, (uint32_t)timestamp_ticks); RTC_CompareSet(0, (uint32_t)timestamp_ticks);
RTC_IntEnable(RTC_IF_COMP0); RTC_IntEnable(RTC_IF_COMP0);
RTC_FreezeEnable(false); RTC_FreezeEnable(false);
} }
inline void lp_ticker_disable_interrupt() { inline void lp_ticker_disable_interrupt()
RTC_IntDisable(RTC_IF_COMP0); {
RTC_IntDisable(RTC_IF_COMP0);
} }
inline void lp_ticker_clear_interrupt() { inline void lp_ticker_clear_interrupt()
RTC_IntClear(RTC_IF_COMP0); {
RTC_IntClear(RTC_IF_COMP0);
} }
timestamp_t lp_ticker_read() { timestamp_t lp_ticker_read()
uint64_t ticks_temp; {
uint64_t ticks = RTC_CounterGet(); uint64_t ticks_temp;
uint64_t ticks = RTC_CounterGet();
/* ticks = counter tick value /* ticks = counter tick value
* timestamp = value in microseconds * timestamp = value in microseconds
* timestamp = ticks * 1.000.000 / RTC frequency * timestamp = ticks * 1.000.000 / RTC frequency
*/ */
ticks_temp = (ticks * 1000000) / (LOW_ENERGY_CLOCK_FREQUENCY / RTC_CLOCKDIV_INT); ticks_temp = (ticks * 1000000) / (LOW_ENERGY_CLOCK_FREQUENCY / RTC_CLOCKDIV_INT);
return (timestamp_t) (ticks_temp & 0xFFFFFFFF); return (timestamp_t) (ticks_temp & 0xFFFFFFFF);
} }
#endif #endif

View File

@ -50,11 +50,11 @@ void mbed_sdk_init()
CMU_ClockSelectSet(cmuClock_LFA, LFXO); CMU_ClockSelectSet(cmuClock_LFA, LFXO);
#endif #endif
#ifdef CMU_LFBCLKSEL_REG #ifdef CMU_LFBCLKSEL_REG
/* cmuClock_LFB (to date) only has LEUART peripherals. /* cmuClock_LFB (to date) only has LEUART peripherals.
* Do NOT set it up here, as LEUARTs might have been initialized * Do NOT set it up here, as LEUARTs might have been initialized
* before this code is called. (Limitation of the override mechanism of ARMCC) * before this code is called. (Limitation of the override mechanism of ARMCC)
*/ */
//TODO: Look for a more elegant fix. //TODO: Look for a more elegant fix.
//CMU_ClockSelectSet(cmuClock_LFB, LFXO); //CMU_ClockSelectSet(cmuClock_LFB, LFXO);
#endif #endif
#ifdef CMU_LFECLKSEL_REG #ifdef CMU_LFECLKSEL_REG
@ -92,7 +92,8 @@ void mbed_sdk_init()
gpio_init_out_ex(&bc_enable, EFM_BC_EN, 1); gpio_init_out_ex(&bc_enable, EFM_BC_EN, 1);
} }
void check_usart_clock(USART_TypeDef* usart, uint32_t clockmask) { void check_usart_clock(USART_TypeDef* usart, uint32_t clockmask)
{
uint32_t freq = 14000000, baudrate; uint32_t freq = 14000000, baudrate;
USART_OVS_TypeDef ovs; USART_OVS_TypeDef ovs;

View File

@ -129,11 +129,11 @@ struct lp_timer_s {
#if DEVICE_SLEEP #if DEVICE_SLEEP
#define NUM_SLEEP_MODES 5 #define NUM_SLEEP_MODES 5
typedef enum { typedef enum {
EM0 = 0, EM0 = 0,
EM1 = 1, EM1 = 1,
EM2 = 2, EM2 = 2,
EM3 = 3, EM3 = 3,
EM4 = 4 EM4 = 4
} sleepstate_enum; } sleepstate_enum;
#endif #endif

View File

@ -30,10 +30,10 @@ void pin_mode(PinName pin, PinMode mode)
MBED_ASSERT(pin != NC); MBED_ASSERT(pin != NC);
/* Enable GPIO clock if not already done */ /* Enable GPIO clock if not already done */
if (!gpio_clock_inited) { if (!gpio_clock_inited) {
CMU_ClockEnable(cmuClock_GPIO, true); CMU_ClockEnable(cmuClock_GPIO, true);
gpio_clock_inited = 1; gpio_clock_inited = 1;
} }
/* Pin and port index encoded in one uint32. /* Pin and port index encoded in one uint32.
* First four bits represent the pin number * First four bits represent the pin number

View File

@ -44,7 +44,7 @@ void port_preinit(port_t *obj, PortName port, int mask, PinDirection dir)
void port_init(port_t *obj, PortName port, int mask, PinDirection dir) void port_init(port_t *obj, PortName port, int mask, PinDirection dir)
{ {
port_preinit(obj, port, mask, dir); port_preinit(obj, port, mask, dir);
port_dir(obj, obj->dir); port_dir(obj, obj->dir);
} }

View File

@ -33,22 +33,23 @@
static int pwm_clockfreq; static int pwm_clockfreq;
static int pwm_prescaler_div; static int pwm_prescaler_div;
uint32_t pwmout_get_channel_route(pwmout_t *obj) { uint32_t pwmout_get_channel_route(pwmout_t *obj)
MBED_ASSERT(obj->channel != (PWMName) NC); {
MBED_ASSERT(obj->channel != (PWMName) NC);
switch (obj->channel) { switch (obj->channel) {
case PWM_CH0: case PWM_CH0:
return TIMER_ROUTE_CC0PEN; return TIMER_ROUTE_CC0PEN;
break; break;
case PWM_CH1: case PWM_CH1:
return TIMER_ROUTE_CC1PEN; return TIMER_ROUTE_CC1PEN;
break; break;
case PWM_CH2: case PWM_CH2:
return TIMER_ROUTE_CC2PEN; return TIMER_ROUTE_CC2PEN;
break; break;
default: default:
return 0; return 0;
} }
} }
void pwmout_enable_pins(pwmout_t *obj, uint8_t enable) void pwmout_enable_pins(pwmout_t *obj, uint8_t enable)
@ -63,8 +64,8 @@ void pwmout_enable_pins(pwmout_t *obj, uint8_t enable)
void pwmout_enable(pwmout_t *obj, uint8_t enable) void pwmout_enable(pwmout_t *obj, uint8_t enable)
{ {
/* Start with default CC (Compare/Capture) channel parameters */ /* Start with default CC (Compare/Capture) channel parameters */
TIMER_InitCC_TypeDef timerCCInit = TIMER_INITCC_DEFAULT; TIMER_InitCC_TypeDef timerCCInit = TIMER_INITCC_DEFAULT;
if (enable) { if (enable) {
/* Set mode to PWM */ /* Set mode to PWM */
timerCCInit.mode = timerCCModePWM; timerCCInit.mode = timerCCModePWM;
@ -76,33 +77,33 @@ void pwmout_enable(pwmout_t *obj, uint8_t enable)
void pwmout_init(pwmout_t *obj, PinName pin) void pwmout_init(pwmout_t *obj, PinName pin)
{ {
obj->channel = (PWMName) pinmap_peripheral(pin, PinMap_PWM); obj->channel = (PWMName) pinmap_peripheral(pin, PinMap_PWM);
obj->pin = pin; obj->pin = pin;
MBED_ASSERT(obj->channel != (PWMName) NC); MBED_ASSERT(obj->channel != (PWMName) NC);
/* Turn on clock */ /* Turn on clock */
CMU_ClockEnable(PWM_TIMER_CLOCK, true); CMU_ClockEnable(PWM_TIMER_CLOCK, true);
/* Turn on timer */ /* Turn on timer */
if(!(PWM_TIMER->STATUS & TIMER_STATUS_RUNNING)) { if(!(PWM_TIMER->STATUS & TIMER_STATUS_RUNNING)) {
TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT; TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;
TIMER_Init(PWM_TIMER, &timerInit); TIMER_Init(PWM_TIMER, &timerInit);
} }
/* Enable correct channel */ /* Enable correct channel */
uint32_t routeloc = pwmout_get_channel_route(obj); uint32_t routeloc = pwmout_get_channel_route(obj);
if(PWM_TIMER->ROUTE & routeloc) { if(PWM_TIMER->ROUTE & routeloc) {
//This channel was already in use //This channel was already in use
//TODO: gracefully handle this case //TODO: gracefully handle this case
} else { } else {
//This channel was unused up to now //This channel was unused up to now
PWM_TIMER->ROUTE |= routeloc; PWM_TIMER->ROUTE |= routeloc;
blockSleepMode(EM1); blockSleepMode(EM1);
//TODO: check if any channel was up already, then don't re-init timer //TODO: check if any channel was up already, then don't re-init timer
pwmout_enable(obj, true); pwmout_enable(obj, true);
pwmout_enable_pins(obj, true); pwmout_enable_pins(obj, true);
} }
/* Route correct channel to location 1 */ /* Route correct channel to location 1 */
PWM_TIMER->ROUTE &= ~_TIMER_ROUTE_LOCATION_MASK; PWM_TIMER->ROUTE &= ~_TIMER_ROUTE_LOCATION_MASK;
@ -115,18 +116,19 @@ void pwmout_init(pwmout_t *obj, PinName pin)
pwmout_period(obj, 0.02); pwmout_period(obj, 0.02);
} }
void pwmout_free(pwmout_t *obj) { void pwmout_free(pwmout_t *obj)
uint32_t routeloc = pwmout_get_channel_route(obj); {
if(PWM_TIMER->ROUTE & routeloc) { uint32_t routeloc = pwmout_get_channel_route(obj);
//This channel was in use, so disable if(PWM_TIMER->ROUTE & routeloc) {
PWM_TIMER->ROUTE &= ~routeloc; //This channel was in use, so disable
pwmout_enable_pins(obj, false); PWM_TIMER->ROUTE &= ~routeloc;
unblockSleepMode(EM1); pwmout_enable_pins(obj, false);
unblockSleepMode(EM1);
//TODO: check if all channels are down, then switch off timer //TODO: check if all channels are down, then switch off timer
} else { } else {
//This channel was disabled already //This channel was disabled already
} }
} }
void pwmout_write(pwmout_t *obj, float value) void pwmout_write(pwmout_t *obj, float value)

View File

@ -28,7 +28,7 @@ static bool rtc_inited = false;
static time_t time_base = 0; static time_t time_base = 0;
static uint32_t useflags = 0; static uint32_t useflags = 0;
static void (*comp0_handler)(void) = NULL; static void (*comp0_handler)(void) = NULL;
#define RTC_LEAST_ACTIVE_SLEEPMODE EM2 #define RTC_LEAST_ACTIVE_SLEEPMODE EM2
@ -37,17 +37,14 @@ void RTC_IRQHandler(void)
{ {
uint32_t flags; uint32_t flags;
flags = RTC_IntGet(); flags = RTC_IntGet();
if (flags & RTC_IF_OF) if (flags & RTC_IF_OF) {
{
RTC_IntClear(RTC_IF_OF); RTC_IntClear(RTC_IF_OF);
/* RTC has overflowed (24 bits). Use time_base as software counter for upper 8 bits. */ /* RTC has overflowed (24 bits). Use time_base as software counter for upper 8 bits. */
time_base += 1 << 24; time_base += 1 << 24;
} }
if (flags & RTC_IF_COMP0) if (flags & RTC_IF_COMP0) {
{
RTC_IntClear(RTC_IF_COMP0); RTC_IntClear(RTC_IF_COMP0);
if (comp0_handler != NULL) if (comp0_handler != NULL) {
{
comp0_handler(); comp0_handler();
} }
} }
@ -58,7 +55,7 @@ void rtc_set_comp0_handler(uint32_t handler)
comp0_handler = (void (*)(void)) handler; comp0_handler = (void (*)(void)) handler;
} }
void rtc_init(void) void rtc_init(void)
{ {
/* Register that the RTC is used for timekeeping. */ /* Register that the RTC is used for timekeeping. */
rtc_init_real(RTC_INIT_RTC); rtc_init_real(RTC_INIT_RTC);
@ -69,8 +66,7 @@ void rtc_init_real(uint32_t flags)
{ {
useflags |= flags; useflags |= flags;
if (!rtc_inited) if (!rtc_inited) {
{
/* Start LFXO and wait until it is stable */ /* Start LFXO and wait until it is stable */
CMU_OscillatorEnable(cmuOsc_LFXO, true, true); CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
@ -103,7 +99,7 @@ void rtc_init_real(uint32_t flags)
} }
} }
void rtc_free(void) void rtc_free(void)
{ {
rtc_free_real(RTC_INIT_RTC); rtc_free_real(RTC_INIT_RTC);
} }
@ -111,11 +107,10 @@ void rtc_free(void)
void rtc_free_real(uint32_t flags) void rtc_free_real(uint32_t flags)
{ {
/* Clear use flag */ /* Clear use flag */
flags &= ~flags; flags &= ~flags;
/* Disable the RTC if it was inited and is no longer in use by anyone. */ /* Disable the RTC if it was inited and is no longer in use by anyone. */
if (rtc_inited && (flags == 0)) if (rtc_inited && (flags == 0)) {
{
NVIC_DisableIRQ(RTC_IRQn); NVIC_DisableIRQ(RTC_IRQn);
RTC_Reset(); RTC_Reset();
CMU_ClockEnable(cmuClock_RTC, false); CMU_ClockEnable(cmuClock_RTC, false);

View File

@ -34,19 +34,19 @@ uint32_t sleep_block_counter[NUM_SLEEP_MODES] = {0};
*/ */
void sleep(void) void sleep(void)
{ {
if (sleep_block_counter[0] > 0) { if (sleep_block_counter[0] > 0) {
// Blocked everything below EM0, so just return // Blocked everything below EM0, so just return
return; return;
} else if (sleep_block_counter[1] > 0) { } else if (sleep_block_counter[1] > 0) {
// Blocked everything below EM1, enter EM1 // Blocked everything below EM1, enter EM1
EMU_EnterEM1(); EMU_EnterEM1();
} else if (sleep_block_counter[2] > 0) { } else if (sleep_block_counter[2] > 0) {
// Blocked everything below EM2, enter EM2 // Blocked everything below EM2, enter EM2
EMU_EnterEM2(true); EMU_EnterEM2(true);
} else if (sleep_block_counter[3] > 0) { } else if (sleep_block_counter[3] > 0) {
// Blocked everything below EM3, enter EM3 // Blocked everything below EM3, enter EM3
EMU_EnterEM3(true); EMU_EnterEM3(true);
} }
return; return;
} }
@ -74,11 +74,11 @@ void deepsleep(void)
* After the peripheral is finished with the operation, it should call unblock with the same state * After the peripheral is finished with the operation, it should call unblock with the same state
* *
*/ */
void blockSleepMode(sleepstate_enum minimumMode) void blockSleepMode(sleepstate_enum minimumMode)
{ {
INT_Disable(); INT_Disable();
sleep_block_counter[minimumMode]++; sleep_block_counter[minimumMode]++;
INT_Enable(); INT_Enable();
} }
/** Unblock the microcontroller from sleeping below a certain mode /** Unblock the microcontroller from sleeping below a certain mode
@ -88,14 +88,13 @@ void blockSleepMode(sleepstate_enum minimumMode)
* *
* This should be called after all transactions on a peripheral are done. * This should be called after all transactions on a peripheral are done.
*/ */
void unblockSleepMode(sleepstate_enum minimumMode) void unblockSleepMode(sleepstate_enum minimumMode)
{ {
INT_Disable(); INT_Disable();
if(sleep_block_counter[minimumMode] > 0) if(sleep_block_counter[minimumMode] > 0) {
{ sleep_block_counter[minimumMode]--;
sleep_block_counter[minimumMode]--; }
} INT_Enable();
INT_Enable();
} }
#endif #endif

View File

@ -35,7 +35,8 @@
static uint16_t fill_word = SPI_FILL_WORD; static uint16_t fill_word = SPI_FILL_WORD;
#define SPI_LEAST_ACTIVE_SLEEPMODE EM1 #define SPI_LEAST_ACTIVE_SLEEPMODE EM1
inline CMU_Clock_TypeDef spi_get_clock_tree(spi_t *obj) { inline CMU_Clock_TypeDef spi_get_clock_tree(spi_t *obj)
{
switch ((int)obj->spi.spi) { switch ((int)obj->spi.spi) {
#ifdef USART0 #ifdef USART0
case SPI_0: case SPI_0:
@ -81,7 +82,8 @@ inline uint8_t spi_get_index(spi_t *obj)
return index; return index;
} }
uint8_t spi_get_module(spi_t *obj) { uint8_t spi_get_module(spi_t *obj)
{
return spi_get_index(obj); return spi_get_index(obj);
} }
@ -200,12 +202,12 @@ void spi_enable(spi_t *obj, uint8_t enable)
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName clk, PinName cs) void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName clk, PinName cs)
{ {
CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_HFPER, true);
spi_preinit(obj, mosi, miso, clk, cs); spi_preinit(obj, mosi, miso, clk, cs);
CMU_ClockEnable(spi_get_clock_tree(obj), true); CMU_ClockEnable(spi_get_clock_tree(obj), true);
usart_init(obj, 100000, usartDatabits8, true, usartClockMode0); usart_init(obj, 100000, usartDatabits8, true, usartClockMode0);
spi_enable_pins(obj, true, mosi, miso, clk, cs); spi_enable_pins(obj, true, mosi, miso, clk, cs);
spi_enable(obj, true); spi_enable(obj, true);
} }
@ -254,8 +256,7 @@ void spi_enable_interrupt(spi_t *obj, uint32_t handler, uint8_t enable)
NVIC_SetVector(IRQvector, handler); NVIC_SetVector(IRQvector, handler);
USART_IntEnable(obj->spi.spi, USART_IEN_RXDATAV); USART_IntEnable(obj->spi.spi, USART_IEN_RXDATAV);
NVIC_EnableIRQ(IRQvector); NVIC_EnableIRQ(IRQvector);
} } else {
else {
NVIC_SetVector(IRQvector, handler); NVIC_SetVector(IRQvector, handler);
USART_IntDisable(obj->spi.spi, USART_IEN_RXDATAV); USART_IntDisable(obj->spi.spi, USART_IEN_RXDATAV);
NVIC_DisableIRQ(IRQvector); NVIC_DisableIRQ(IRQvector);
@ -400,11 +401,11 @@ uint8_t spi_active(spi_t *obj)
void spi_buffer_set(spi_t *obj, void *tx, uint32_t tx_length, void *rx, uint32_t rx_length, uint8_t bit_width) void spi_buffer_set(spi_t *obj, void *tx, uint32_t tx_length, void *rx, uint32_t rx_length, uint8_t bit_width)
{ {
uint32_t i; uint32_t i;
uint16_t *tx_ptr = (uint16_t *) tx; uint16_t *tx_ptr = (uint16_t *) tx;
tx_length *= (bit_width >> 3); tx_length *= (bit_width >> 3);
rx_length *= (bit_width >> 3); rx_length *= (bit_width >> 3);
obj->tx_buff.buffer = tx; obj->tx_buff.buffer = tx;
obj->rx_buff.buffer = rx; obj->rx_buff.buffer = rx;
@ -416,123 +417,123 @@ void spi_buffer_set(spi_t *obj, void *tx, uint32_t tx_length, void *rx, uint32_t
obj->rx_buff.width = bit_width; obj->rx_buff.width = bit_width;
if((obj->spi.bits == 9) && (tx != 0)) { if((obj->spi.bits == 9) && (tx != 0)) {
// Make sure we don't have inadvertent non-zero bits outside 9-bit frames which could trigger unwanted operation // Make sure we don't have inadvertent non-zero bits outside 9-bit frames which could trigger unwanted operation
for(i = 0; i < (tx_length / 2); i++) { for(i = 0; i < (tx_length / 2); i++) {
tx_ptr[i] &= 0x1FF; tx_ptr[i] &= 0x1FF;
} }
} }
} }
static void spi_buffer_tx_write(spi_t *obj) static void spi_buffer_tx_write(spi_t *obj)
{ {
uint32_t data; uint32_t data;
// This routine gets triggered on TXBL (= buffer empty), so check to see if we can write a double value // This routine gets triggered on TXBL (= buffer empty), so check to see if we can write a double value
if (obj->spi.bits % 9 != 0) { if (obj->spi.bits % 9 != 0) {
// No special 9-bit scenario // No special 9-bit scenario
if((obj->tx_buff.pos < obj->tx_buff.length - 1) && ((obj->tx_buff.pos & 0x1) == 0)) { if((obj->tx_buff.pos < obj->tx_buff.length - 1) && ((obj->tx_buff.pos & 0x1) == 0)) {
// write double frame // write double frame
if (obj->tx_buff.buffer == (void *)0) { if (obj->tx_buff.buffer == (void *)0) {
data = SPI_FILL_WORD; data = SPI_FILL_WORD;
} else { } else {
uint16_t *tx = (uint16_t *)(obj->tx_buff.buffer); uint16_t *tx = (uint16_t *)(obj->tx_buff.buffer);
data = tx[obj->tx_buff.pos / 2] & 0xFFFF; data = tx[obj->tx_buff.pos / 2] & 0xFFFF;
} }
obj->tx_buff.pos += 2; obj->tx_buff.pos += 2;
obj->spi.spi->TXDOUBLE = data; obj->spi.spi->TXDOUBLE = data;
} else if (obj->tx_buff.pos < obj->tx_buff.length) { } else if (obj->tx_buff.pos < obj->tx_buff.length) {
// write single frame // write single frame
if (obj->tx_buff.buffer == (void *)0) { if (obj->tx_buff.buffer == (void *)0) {
data = SPI_FILL_WORD & 0xFF; data = SPI_FILL_WORD & 0xFF;
} else { } else {
uint8_t *tx = (uint8_t *)(obj->tx_buff.buffer); uint8_t *tx = (uint8_t *)(obj->tx_buff.buffer);
data = tx[obj->tx_buff.pos] & 0xFF; data = tx[obj->tx_buff.pos] & 0xFF;
} }
obj->tx_buff.pos++; obj->tx_buff.pos++;
obj->spi.spi->TXDATA = data; obj->spi.spi->TXDATA = data;
} }
} else { } else {
// 9-bit frame // 9-bit frame
if(obj->tx_buff.pos < obj->tx_buff.length - 3) { if(obj->tx_buff.pos < obj->tx_buff.length - 3) {
// write double frame // write double frame
if (obj->tx_buff.buffer == (void *)0) { if (obj->tx_buff.buffer == (void *)0) {
data = ((SPI_FILL_WORD & 0x01FF) << 16) | (SPI_FILL_WORD & 0x1FF); data = ((SPI_FILL_WORD & 0x01FF) << 16) | (SPI_FILL_WORD & 0x1FF);
} else { } else {
uint32_t *tx = (uint32_t *)(obj->tx_buff.buffer); uint32_t *tx = (uint32_t *)(obj->tx_buff.buffer);
data = tx[obj->tx_buff.pos / 4] & 0x01FF01FF; data = tx[obj->tx_buff.pos / 4] & 0x01FF01FF;
} }
obj->tx_buff.pos += 4; obj->tx_buff.pos += 4;
obj->spi.spi->TXDOUBLEX = data; obj->spi.spi->TXDOUBLEX = data;
} else if (obj->tx_buff.pos < obj->tx_buff.length - 1) { } else if (obj->tx_buff.pos < obj->tx_buff.length - 1) {
// write single frame // write single frame
if (obj->tx_buff.buffer == (void *)0) { if (obj->tx_buff.buffer == (void *)0) {
data = SPI_FILL_WORD & 0x01FF; data = SPI_FILL_WORD & 0x01FF;
} else { } else {
uint16_t *tx = (uint16_t *)(obj->tx_buff.buffer); uint16_t *tx = (uint16_t *)(obj->tx_buff.buffer);
data = tx[obj->tx_buff.pos / 2] & 0x01FF; data = tx[obj->tx_buff.pos / 2] & 0x01FF;
} }
obj->tx_buff.pos += 2; obj->tx_buff.pos += 2;
obj->spi.spi->TXDATAX = data; obj->spi.spi->TXDATAX = data;
} }
} }
} }
static void spi_buffer_rx_read(spi_t *obj) static void spi_buffer_rx_read(spi_t *obj)
{ {
if (obj->spi.bits % 9 != 0) { if (obj->spi.bits % 9 != 0) {
if ((obj->spi.spi->STATUS & USART_STATUS_RXFULL) && (obj->rx_buff.pos < obj->rx_buff.length - 1) && ((obj->rx_buff.pos % 2) == 0)) { if ((obj->spi.spi->STATUS & USART_STATUS_RXFULL) && (obj->rx_buff.pos < obj->rx_buff.length - 1) && ((obj->rx_buff.pos % 2) == 0)) {
// Read max 16 bits from buffer to speed things up // Read max 16 bits from buffer to speed things up
uint32_t data = (uint32_t)obj->spi.spi->RXDOUBLE; //read the data but store only if rx is set and not full uint32_t data = (uint32_t)obj->spi.spi->RXDOUBLE; //read the data but store only if rx is set and not full
if (obj->rx_buff.buffer) { if (obj->rx_buff.buffer) {
uint16_t *rx = (uint16_t *)(obj->rx_buff.buffer); uint16_t *rx = (uint16_t *)(obj->rx_buff.buffer);
rx[obj->rx_buff.pos / 2] = data & 0xFFFF; rx[obj->rx_buff.pos / 2] = data & 0xFFFF;
obj->rx_buff.pos += 2; obj->rx_buff.pos += 2;
} }
} else if ((obj->spi.spi->STATUS & (USART_STATUS_RXDATAV | USART_STATUS_RXFULL)) && (obj->rx_buff.pos < obj->rx_buff.length)) { } else if ((obj->spi.spi->STATUS & (USART_STATUS_RXDATAV | USART_STATUS_RXFULL)) && (obj->rx_buff.pos < obj->rx_buff.length)) {
// Read 8 bits from buffer // Read 8 bits from buffer
while((obj->spi.spi->STATUS & (USART_STATUS_RXDATAV | USART_STATUS_RXFULL)) && (obj->rx_buff.pos < obj->rx_buff.length)) { while((obj->spi.spi->STATUS & (USART_STATUS_RXDATAV | USART_STATUS_RXFULL)) && (obj->rx_buff.pos < obj->rx_buff.length)) {
uint32_t data = (uint32_t)obj->spi.spi->RXDATA; //read the data but store only if rx is set and not full uint32_t data = (uint32_t)obj->spi.spi->RXDATA; //read the data but store only if rx is set and not full
if (obj->rx_buff.buffer) { if (obj->rx_buff.buffer) {
uint8_t *rx = (uint8_t *)(obj->rx_buff.buffer); uint8_t *rx = (uint8_t *)(obj->rx_buff.buffer);
rx[obj->rx_buff.pos] = data & 0xFF; rx[obj->rx_buff.pos] = data & 0xFF;
obj->rx_buff.pos++; obj->rx_buff.pos++;
} }
} }
} else if (obj->spi.spi->STATUS & USART_STATUS_RXFULL) { } else if (obj->spi.spi->STATUS & USART_STATUS_RXFULL) {
// Read from the buffer to lower the interrupt flag // Read from the buffer to lower the interrupt flag
volatile uint32_t data = (uint32_t)obj->spi.spi->RXDOUBLE; volatile uint32_t data = (uint32_t)obj->spi.spi->RXDOUBLE;
} else if (obj->spi.spi->STATUS & USART_STATUS_RXDATAV) { } else if (obj->spi.spi->STATUS & USART_STATUS_RXDATAV) {
// Read from the buffer to lower the interrupt flag // Read from the buffer to lower the interrupt flag
volatile uint32_t data = (uint32_t)obj->spi.spi->RXDATA; volatile uint32_t data = (uint32_t)obj->spi.spi->RXDATA;
} }
} else { } else {
// Data bits is multiple of 9, so use the extended registers // Data bits is multiple of 9, so use the extended registers
if ((obj->spi.spi->STATUS & USART_STATUS_RXFULL) && (obj->rx_buff.pos < obj->rx_buff.length - 3) && ((obj->rx_buff.pos % 4) == 0)) { if ((obj->spi.spi->STATUS & USART_STATUS_RXFULL) && (obj->rx_buff.pos < obj->rx_buff.length - 3) && ((obj->rx_buff.pos % 4) == 0)) {
// Read max 18 bits from buffer to speed things up // Read max 18 bits from buffer to speed things up
uint32_t data = (uint32_t)obj->spi.spi->RXDOUBLEX; //read the data but store only if rx is set and will not overflow uint32_t data = (uint32_t)obj->spi.spi->RXDOUBLEX; //read the data but store only if rx is set and will not overflow
if (obj->rx_buff.buffer) { if (obj->rx_buff.buffer) {
uint16_t *rx = (uint16_t *)(obj->rx_buff.buffer); uint16_t *rx = (uint16_t *)(obj->rx_buff.buffer);
rx[obj->rx_buff.pos / 2] = data & 0x000001FF; rx[obj->rx_buff.pos / 2] = data & 0x000001FF;
rx[(obj->rx_buff.pos / 2) + 1] = (data & 0x01FF0000) >> 16; rx[(obj->rx_buff.pos / 2) + 1] = (data & 0x01FF0000) >> 16;
obj->rx_buff.pos += 4; obj->rx_buff.pos += 4;
} }
} else if ((obj->spi.spi->STATUS & (USART_STATUS_RXDATAV | USART_STATUS_RXFULL)) && (obj->rx_buff.pos < obj->rx_buff.length - 1)) { } else if ((obj->spi.spi->STATUS & (USART_STATUS_RXDATAV | USART_STATUS_RXFULL)) && (obj->rx_buff.pos < obj->rx_buff.length - 1)) {
// Read 9 bits from buffer // Read 9 bits from buffer
while((obj->spi.spi->STATUS & (USART_STATUS_RXDATAV | USART_STATUS_RXFULL)) && (obj->rx_buff.pos < obj->rx_buff.length - 1)) { while((obj->spi.spi->STATUS & (USART_STATUS_RXDATAV | USART_STATUS_RXFULL)) && (obj->rx_buff.pos < obj->rx_buff.length - 1)) {
uint32_t data = (uint32_t)obj->spi.spi->RXDATAX; //read the data but store only if rx is set and not full uint32_t data = (uint32_t)obj->spi.spi->RXDATAX; //read the data but store only if rx is set and not full
if (obj->rx_buff.buffer) { if (obj->rx_buff.buffer) {
uint16_t *rx = (uint16_t *)(obj->rx_buff.buffer); uint16_t *rx = (uint16_t *)(obj->rx_buff.buffer);
rx[obj->rx_buff.pos / 2] = data & 0x01FF; rx[obj->rx_buff.pos / 2] = data & 0x01FF;
obj->rx_buff.pos += 2; obj->rx_buff.pos += 2;
} }
} }
} else if (obj->spi.spi->STATUS & USART_STATUS_RXFULL) { } else if (obj->spi.spi->STATUS & USART_STATUS_RXFULL) {
// Read from the buffer to lower the interrupt flag // Read from the buffer to lower the interrupt flag
volatile uint32_t data = (uint32_t)obj->spi.spi->RXDOUBLEX; volatile uint32_t data = (uint32_t)obj->spi.spi->RXDOUBLEX;
} else if (obj->spi.spi->STATUS & USART_STATUS_RXDATAV) { } else if (obj->spi.spi->STATUS & USART_STATUS_RXDATAV) {
// Read from the buffer to lower the interrupt flag // Read from the buffer to lower the interrupt flag
volatile uint32_t data = (uint32_t)obj->spi.spi->RXDATAX; volatile uint32_t data = (uint32_t)obj->spi.spi->RXDATAX;
} }
} }
} }
int spi_master_write_asynch(spi_t *obj) int spi_master_write_asynch(spi_t *obj)
@ -602,7 +603,7 @@ uint32_t spi_event_check(spi_t *obj)
} }
if(quit == true) { if(quit == true) {
event |= SPI_EVENT_INTERNAL_TRANSFER_COMPLETE; event |= SPI_EVENT_INTERNAL_TRANSFER_COMPLETE;
} }
return event; return event;
@ -633,7 +634,8 @@ void transferComplete(unsigned int channel, bool primary, void *user)
* *
* return value: whether the channels were acquired successfully (true) or not. * return value: whether the channels were acquired successfully (true) or not.
******************************************/ ******************************************/
bool spi_allocate_dma(spi_t *obj) { bool spi_allocate_dma(spi_t *obj)
{
int dmaChannelIn, dmaChannelOut; int dmaChannelIn, dmaChannelOut;
dmaChannelIn = dma_channel_allocate(DMA_CAP_NONE); dmaChannelIn = dma_channel_allocate(DMA_CAP_NONE);
if (dmaChannelIn == DMA_ERROR_OUT_OF_CHANNELS) { if (dmaChannelIn == DMA_ERROR_OUT_OF_CHANNELS) {
@ -722,7 +724,7 @@ static void spi_master_dma_channel_setup(spi_t *obj, void* callback)
txChnlCfg.enableInt = true; txChnlCfg.enableInt = true;
txChnlCfg.cb = &(obj->spi.dmaOptionsTX.dmaCallback); txChnlCfg.cb = &(obj->spi.dmaOptionsTX.dmaCallback);
switch ((int)obj->spi.spi) { switch ((int)obj->spi.spi) {
#ifdef USART0 #ifdef USART0
case SPI_0: case SPI_0:
rxChnlCfg.select = DMAREQ_USART0_RXDATAV; rxChnlCfg.select = DMAREQ_USART0_RXDATAV;
@ -759,7 +761,8 @@ static void spi_master_dma_channel_setup(spi_t *obj, void* callback)
* * tx_length: how many bytes will get sent. * * tx_length: how many bytes will get sent.
* * rx_length: how many bytes will get received. If > tx_length, TX will get padded with n lower bits of SPI_FILL_WORD. * * rx_length: how many bytes will get received. If > tx_length, TX will get padded with n lower bits of SPI_FILL_WORD.
******************************************/ ******************************************/
static void spi_activate_dma(spi_t *obj, void* rxdata, void* txdata, int tx_length, int rx_length) { static void spi_activate_dma(spi_t *obj, void* rxdata, void* txdata, int tx_length, int rx_length)
{
/* DMA descriptors */ /* DMA descriptors */
DMA_CfgDescr_TypeDef rxDescrCfg; DMA_CfgDescr_TypeDef rxDescrCfg;
DMA_CfgDescr_TypeDef txDescrCfg; DMA_CfgDescr_TypeDef txDescrCfg;
@ -768,81 +771,81 @@ static void spi_activate_dma(spi_t *obj, void* rxdata, void* txdata, int tx_leng
obj->tx_buff.pos = tx_length; obj->tx_buff.pos = tx_length;
if(obj->spi.bits != 9) { if(obj->spi.bits != 9) {
/* Only activate RX DMA if a receive buffer is specified */ /* Only activate RX DMA if a receive buffer is specified */
if (rxdata != NULL) { if (rxdata != NULL) {
// Setting up channel descriptor // Setting up channel descriptor
rxDescrCfg.dstInc = dmaDataInc1; rxDescrCfg.dstInc = dmaDataInc1;
rxDescrCfg.srcInc = dmaDataIncNone; rxDescrCfg.srcInc = dmaDataIncNone;
rxDescrCfg.size = dmaDataSize1; rxDescrCfg.size = dmaDataSize1;
rxDescrCfg.arbRate = dmaArbitrate1; rxDescrCfg.arbRate = dmaArbitrate1;
rxDescrCfg.hprot = 0; rxDescrCfg.hprot = 0;
DMA_CfgDescr(obj->spi.dmaOptionsRX.dmaChannel, true, &rxDescrCfg); DMA_CfgDescr(obj->spi.dmaOptionsRX.dmaChannel, true, &rxDescrCfg);
// Clear RX registers - Useful if previous command transfered don't // Clear RX registers - Useful if previous command transfered don't
obj->spi.spi->CMD = USART_CMD_CLEARRX; obj->spi.spi->CMD = USART_CMD_CLEARRX;
/* Activate RX channel */ /* Activate RX channel */
DMA_ActivateBasic(obj->spi.dmaOptionsRX.dmaChannel, true, false, rxdata, (void *)&(obj->spi.spi->RXDATA), DMA_ActivateBasic(obj->spi.dmaOptionsRX.dmaChannel, true, false, rxdata, (void *)&(obj->spi.spi->RXDATA),
rx_length - 1); rx_length - 1);
} }
// buffer with all FFs. // buffer with all FFs.
/* Setting up channel descriptor */ /* Setting up channel descriptor */
txDescrCfg.dstInc = dmaDataIncNone; txDescrCfg.dstInc = dmaDataIncNone;
txDescrCfg.srcInc = (txdata == 0 ? dmaDataIncNone : (obj->spi.bits <= 8 ? dmaDataInc1 : dmaDataInc2)); //Do not increment source pointer when there is no transmit buffer txDescrCfg.srcInc = (txdata == 0 ? dmaDataIncNone : (obj->spi.bits <= 8 ? dmaDataInc1 : dmaDataInc2)); //Do not increment source pointer when there is no transmit buffer
txDescrCfg.size = (obj->spi.bits <= 8 ? dmaDataSize1 : dmaDataSize2); //When frame size > 9, we can use TXDOUBLE to save bandwidth txDescrCfg.size = (obj->spi.bits <= 8 ? dmaDataSize1 : dmaDataSize2); //When frame size > 9, we can use TXDOUBLE to save bandwidth
txDescrCfg.arbRate = dmaArbitrate1; txDescrCfg.arbRate = dmaArbitrate1;
txDescrCfg.hprot = 0; txDescrCfg.hprot = 0;
DMA_CfgDescr(obj->spi.dmaOptionsTX.dmaChannel, true, &txDescrCfg); DMA_CfgDescr(obj->spi.dmaOptionsTX.dmaChannel, true, &txDescrCfg);
/* Clear TX registers */ /* Clear TX registers */
obj->spi.spi->CMD = USART_CMD_CLEARTX; obj->spi.spi->CMD = USART_CMD_CLEARTX;
/* Activate TX channel */ /* Activate TX channel */
DMA_ActivateBasic( obj->spi.dmaOptionsTX.dmaChannel, DMA_ActivateBasic( obj->spi.dmaOptionsTX.dmaChannel,
true, true,
false, false,
(obj->spi.bits <= 8 ? (void *)&(obj->spi.spi->TXDATA) : (void *)&(obj->spi.spi->TXDOUBLE)), //When frame size > 9, point to TXDOUBLE (obj->spi.bits <= 8 ? (void *)&(obj->spi.spi->TXDATA) : (void *)&(obj->spi.spi->TXDOUBLE)), //When frame size > 9, point to TXDOUBLE
(txdata == 0 ? &fill_word : txdata), // When there is nothing to transmit, point to static fill word (txdata == 0 ? &fill_word : txdata), // When there is nothing to transmit, point to static fill word
(obj->spi.bits <= 8 ? tx_length - 1 : (tx_length / 2) - 1)); // When using TXDOUBLE, recalculate transfer length (obj->spi.bits <= 8 ? tx_length - 1 : (tx_length / 2) - 1)); // When using TXDOUBLE, recalculate transfer length
} else { } else {
/* Frame size == 9 */ /* Frame size == 9 */
/* Only activate RX DMA if a receive buffer is specified */ /* Only activate RX DMA if a receive buffer is specified */
if (rxdata != NULL) { if (rxdata != NULL) {
// Setting up channel descriptor // Setting up channel descriptor
rxDescrCfg.dstInc = dmaDataInc2; rxDescrCfg.dstInc = dmaDataInc2;
rxDescrCfg.srcInc = dmaDataIncNone; rxDescrCfg.srcInc = dmaDataIncNone;
rxDescrCfg.size = dmaDataSize2; rxDescrCfg.size = dmaDataSize2;
rxDescrCfg.arbRate = dmaArbitrate1; rxDescrCfg.arbRate = dmaArbitrate1;
rxDescrCfg.hprot = 0; rxDescrCfg.hprot = 0;
DMA_CfgDescr(obj->spi.dmaOptionsRX.dmaChannel, true, &rxDescrCfg); DMA_CfgDescr(obj->spi.dmaOptionsRX.dmaChannel, true, &rxDescrCfg);
// Clear RX registers - Useful if previous command transfered don't // Clear RX registers - Useful if previous command transfered don't
obj->spi.spi->CMD = USART_CMD_CLEARRX; obj->spi.spi->CMD = USART_CMD_CLEARRX;
/* Activate RX channel */ /* Activate RX channel */
DMA_ActivateBasic(obj->spi.dmaOptionsRX.dmaChannel, true, false, rxdata, (void *)&(obj->spi.spi->RXDATAX), DMA_ActivateBasic(obj->spi.dmaOptionsRX.dmaChannel, true, false, rxdata, (void *)&(obj->spi.spi->RXDATAX),
(rx_length / 2) - 1); (rx_length / 2) - 1);
} }
/* Setting up channel descriptor */ /* Setting up channel descriptor */
txDescrCfg.dstInc = dmaDataIncNone; txDescrCfg.dstInc = dmaDataIncNone;
txDescrCfg.srcInc = (txdata == 0 ? dmaDataIncNone : dmaDataInc2); //Do not increment source pointer when there is no transmit buffer txDescrCfg.srcInc = (txdata == 0 ? dmaDataIncNone : dmaDataInc2); //Do not increment source pointer when there is no transmit buffer
txDescrCfg.size = dmaDataSize2; //When frame size > 9, we can use TXDOUBLE to save bandwidth txDescrCfg.size = dmaDataSize2; //When frame size > 9, we can use TXDOUBLE to save bandwidth
txDescrCfg.arbRate = dmaArbitrate1; txDescrCfg.arbRate = dmaArbitrate1;
txDescrCfg.hprot = 0; txDescrCfg.hprot = 0;
DMA_CfgDescr(obj->spi.dmaOptionsTX.dmaChannel, true, &txDescrCfg); DMA_CfgDescr(obj->spi.dmaOptionsTX.dmaChannel, true, &txDescrCfg);
/* Clear TX registers */ /* Clear TX registers */
obj->spi.spi->CMD = USART_CMD_CLEARTX; obj->spi.spi->CMD = USART_CMD_CLEARTX;
/* Activate TX channel */ /* Activate TX channel */
DMA_ActivateBasic( obj->spi.dmaOptionsTX.dmaChannel, DMA_ActivateBasic( obj->spi.dmaOptionsTX.dmaChannel,
true, true,
false, false,
(void *)&(obj->spi.spi->TXDATAX), //When frame size > 9, point to TXDOUBLE (void *)&(obj->spi.spi->TXDATAX), //When frame size > 9, point to TXDOUBLE
(txdata == 0 ? &fill_word : txdata), // When there is nothing to transmit, point to static fill word (txdata == 0 ? &fill_word : txdata), // When there is nothing to transmit, point to static fill word
(tx_length / 2) - 1); // When using TXDOUBLE, recalculate transfer length (tx_length / 2) - 1); // When using TXDOUBLE, recalculate transfer length
} }
} }
@ -863,9 +866,10 @@ static void spi_activate_dma(spi_t *obj, void* rxdata, void* txdata, int tx_leng
* If the previous transfer has kept the channel, that channel will continue to get used. * If the previous transfer has kept the channel, that channel will continue to get used.
* *
********************************************************************/ ********************************************************************/
void spi_master_transfer_dma(spi_t *obj, void *txdata, void *rxdata, int tx_length, int rx_length, void* cb, DMAUsage hint) { void spi_master_transfer_dma(spi_t *obj, void *txdata, void *rxdata, int tx_length, int rx_length, void* cb, DMAUsage hint)
/* Init DMA here to include it in the power figure */ {
dma_init(); /* Init DMA here to include it in the power figure */
dma_init();
/* If the DMA channels are already allocated, we can assume they have been setup already */ /* If the DMA channels are already allocated, we can assume they have been setup already */
if (hint != DMA_USAGE_NEVER && obj->spi.dmaOptionsTX.dmaUsageState == DMA_USAGE_ALLOCATED) { if (hint != DMA_USAGE_NEVER && obj->spi.dmaOptionsTX.dmaUsageState == DMA_USAGE_ALLOCATED) {
/* setup has already been done, so just activate the transfer */ /* setup has already been done, so just activate the transfer */
@ -910,36 +914,37 @@ void spi_master_transfer_dma(spi_t *obj, void *txdata, void *rxdata, int tx_leng
* @param[in] handler SPI interrupt handler * @param[in] handler SPI interrupt handler
* @param[in] hint A suggestion for how to use DMA with this transfer * @param[in] hint A suggestion for how to use DMA with this transfer
*/ */
void spi_master_transfer(spi_t *obj, void *tx, size_t tx_length, void *rx, size_t rx_length, uint8_t bit_width, uint32_t handler, uint32_t event, DMAUsage hint) { void spi_master_transfer(spi_t *obj, void *tx, size_t tx_length, void *rx, size_t rx_length, uint8_t bit_width, uint32_t handler, uint32_t event, DMAUsage hint)
if( spi_active(obj) ) return; {
if( spi_active(obj) ) return;
/* update fill word if on 9-bit frame size */ /* update fill word if on 9-bit frame size */
if(obj->spi.bits == 9) fill_word = SPI_FILL_WORD & 0x1FF; if(obj->spi.bits == 9) fill_word = SPI_FILL_WORD & 0x1FF;
else fill_word = SPI_FILL_WORD; else fill_word = SPI_FILL_WORD;
/* check corner case */ /* check corner case */
if(tx_length == 0) { if(tx_length == 0) {
tx_length = rx_length; tx_length = rx_length;
tx = (void*) 0; tx = (void*) 0;
} }
/* First, set the buffer */ /* First, set the buffer */
spi_buffer_set(obj, tx, tx_length, rx, rx_length, bit_width); spi_buffer_set(obj, tx, tx_length, rx, rx_length, bit_width);
/* Then, enable the events */ /* Then, enable the events */
spi_enable_event(obj, SPI_EVENT_ALL, false); spi_enable_event(obj, SPI_EVENT_ALL, false);
spi_enable_event(obj, event, true); spi_enable_event(obj, event, true);
/* Be tricky on how we handle increased bit widths in the buffer... Handling on byte-basis */ /* Be tricky on how we handle increased bit widths in the buffer... Handling on byte-basis */
// div 8 = shift right 3 // div 8 = shift right 3
tx_length = tx_length * (bit_width >> 3); tx_length = tx_length * (bit_width >> 3);
rx_length = rx_length * (bit_width >> 3); rx_length = rx_length * (bit_width >> 3);
// Set the sleep mode // Set the sleep mode
blockSleepMode(SPI_LEAST_ACTIVE_SLEEPMODE); blockSleepMode(SPI_LEAST_ACTIVE_SLEEPMODE);
/* And kick off the transfer */ /* And kick off the transfer */
spi_master_transfer_dma(obj, tx, rx, tx_length, rx_length, (void*)handler, hint); spi_master_transfer_dma(obj, tx, rx, tx_length, rx_length, (void*)handler, hint);
} }
@ -953,7 +958,8 @@ void spi_master_transfer(spi_t *obj, void *tx, size_t tx_length, void *rx, size_
* return: event mask. Currently only 0 or SPI_EVENT_COMPLETE upon transfer completion. * return: event mask. Currently only 0 or SPI_EVENT_COMPLETE upon transfer completion.
* *
********************************************************************/ ********************************************************************/
uint32_t spi_irq_handler_asynch(spi_t* obj) { uint32_t spi_irq_handler_asynch(spi_t* obj)
{
/* Determine whether the current scenario is DMA or IRQ, and act accordingly */ /* Determine whether the current scenario is DMA or IRQ, and act accordingly */
@ -962,56 +968,55 @@ uint32_t spi_irq_handler_asynch(spi_t* obj) {
/* If there is an RX transfer ongoing, wait for it to finish */ /* If there is an RX transfer ongoing, wait for it to finish */
if (DMA_ChannelEnabled(obj->spi.dmaOptionsRX.dmaChannel)) { if (DMA_ChannelEnabled(obj->spi.dmaOptionsRX.dmaChannel)) {
/* Check if we need to kick off TX transfer again to force more incoming data. */ /* Check if we need to kick off TX transfer again to force more incoming data. */
if (!DMA_ChannelEnabled(obj->spi.dmaOptionsTX.dmaChannel) && (obj->tx_buff.pos < obj->rx_buff.length)) { if (!DMA_ChannelEnabled(obj->spi.dmaOptionsTX.dmaChannel) && (obj->tx_buff.pos < obj->rx_buff.length)) {
//Save state of TX transfer amount //Save state of TX transfer amount
int length_diff = obj->rx_buff.length - obj->tx_buff.pos; int length_diff = obj->rx_buff.length - obj->tx_buff.pos;
obj->tx_buff.pos = obj->rx_buff.length; obj->tx_buff.pos = obj->rx_buff.length;
//Kick off a new DMA transfer //Kick off a new DMA transfer
DMA_CfgDescr_TypeDef txDescrCfg; DMA_CfgDescr_TypeDef txDescrCfg;
if(obj->spi.bits != 9) { if(obj->spi.bits != 9) {
fill_word = SPI_FILL_WORD; fill_word = SPI_FILL_WORD;
/* Setting up channel descriptor */ /* Setting up channel descriptor */
txDescrCfg.dstInc = dmaDataIncNone; txDescrCfg.dstInc = dmaDataIncNone;
txDescrCfg.srcInc = dmaDataIncNone; //Do not increment source pointer when there is no transmit buffer txDescrCfg.srcInc = dmaDataIncNone; //Do not increment source pointer when there is no transmit buffer
txDescrCfg.size = (obj->spi.bits <= 8 ? dmaDataSize1 : dmaDataSize2); //When frame size > 9, we can use TXDOUBLE to save bandwidth txDescrCfg.size = (obj->spi.bits <= 8 ? dmaDataSize1 : dmaDataSize2); //When frame size > 9, we can use TXDOUBLE to save bandwidth
txDescrCfg.arbRate = dmaArbitrate1; txDescrCfg.arbRate = dmaArbitrate1;
txDescrCfg.hprot = 0; txDescrCfg.hprot = 0;
DMA_CfgDescr(obj->spi.dmaOptionsTX.dmaChannel, true, &txDescrCfg); DMA_CfgDescr(obj->spi.dmaOptionsTX.dmaChannel, true, &txDescrCfg);
/* Activate TX channel */ /* Activate TX channel */
DMA_ActivateBasic( obj->spi.dmaOptionsTX.dmaChannel, DMA_ActivateBasic( obj->spi.dmaOptionsTX.dmaChannel,
true, true,
false, false,
(obj->spi.bits <= 8 ? (void *)&(obj->spi.spi->TXDATA) : (void *)&(obj->spi.spi->TXDOUBLE)), //When frame size > 9, point to TXDOUBLE (obj->spi.bits <= 8 ? (void *)&(obj->spi.spi->TXDATA) : (void *)&(obj->spi.spi->TXDOUBLE)), //When frame size > 9, point to TXDOUBLE
&fill_word, // When there is nothing to transmit, point to static fill word &fill_word, // When there is nothing to transmit, point to static fill word
(obj->spi.bits <= 8 ? length_diff - 1 : (length_diff / 2) - 1)); // When using TXDOUBLE, recalculate transfer length (obj->spi.bits <= 8 ? length_diff - 1 : (length_diff / 2) - 1)); // When using TXDOUBLE, recalculate transfer length
} else { } else {
/* Setting up channel descriptor */ /* Setting up channel descriptor */
fill_word = SPI_FILL_WORD & 0x1FF; fill_word = SPI_FILL_WORD & 0x1FF;
txDescrCfg.dstInc = dmaDataIncNone; txDescrCfg.dstInc = dmaDataIncNone;
txDescrCfg.srcInc = dmaDataIncNone; //Do not increment source pointer when there is no transmit buffer txDescrCfg.srcInc = dmaDataIncNone; //Do not increment source pointer when there is no transmit buffer
txDescrCfg.size = dmaDataSize2; //When frame size > 9, we can use TXDOUBLE to save bandwidth txDescrCfg.size = dmaDataSize2; //When frame size > 9, we can use TXDOUBLE to save bandwidth
txDescrCfg.arbRate = dmaArbitrate1; txDescrCfg.arbRate = dmaArbitrate1;
txDescrCfg.hprot = 0; txDescrCfg.hprot = 0;
DMA_CfgDescr(obj->spi.dmaOptionsTX.dmaChannel, true, &txDescrCfg); DMA_CfgDescr(obj->spi.dmaOptionsTX.dmaChannel, true, &txDescrCfg);
DMA_ActivateBasic( obj->spi.dmaOptionsTX.dmaChannel, DMA_ActivateBasic( obj->spi.dmaOptionsTX.dmaChannel,
true, true,
false, false,
(void *)&(obj->spi.spi->TXDATAX), //When frame size > 9, point to TXDOUBLE (void *)&(obj->spi.spi->TXDATAX), //When frame size > 9, point to TXDOUBLE
&fill_word, // When there is nothing to transmit, point to static fill word &fill_word, // When there is nothing to transmit, point to static fill word
(length_diff / 2) - 1); (length_diff / 2) - 1);
} }
} } else return 0;
else return 0;
} }
/* If there is still a TX transfer ongoing (tx_length > rx_length), wait for it to finish */ /* If there is still a TX transfer ongoing (tx_length > rx_length), wait for it to finish */
if (DMA_ChannelEnabled(obj->spi.dmaOptionsTX.dmaChannel)) { if (DMA_ChannelEnabled(obj->spi.dmaOptionsTX.dmaChannel)) {
return 0; return 0;
} }
/* Release the dma channels if they were opportunistically allocated */ /* Release the dma channels if they were opportunistically allocated */
@ -1054,28 +1059,29 @@ uint32_t spi_irq_handler_asynch(spi_t* obj) {
* *
* @param obj The SPI peripheral to stop * @param obj The SPI peripheral to stop
*/ */
void spi_abort_asynch(spi_t *obj) { void spi_abort_asynch(spi_t *obj)
{
// If we're not currently transferring, then there's nothing to do here // If we're not currently transferring, then there's nothing to do here
if(spi_active(obj) != 0) return; if(spi_active(obj) != 0) return;
// Determine whether we're running DMA or interrupt // Determine whether we're running DMA or interrupt
if (obj->spi.dmaOptionsTX.dmaUsageState == DMA_USAGE_ALLOCATED || obj->spi.dmaOptionsTX.dmaUsageState == DMA_USAGE_TEMPORARY_ALLOCATED) { if (obj->spi.dmaOptionsTX.dmaUsageState == DMA_USAGE_ALLOCATED || obj->spi.dmaOptionsTX.dmaUsageState == DMA_USAGE_TEMPORARY_ALLOCATED) {
// Cancel the DMA transfers // Cancel the DMA transfers
DMA_ChannelEnable(obj->spi.dmaOptionsTX.dmaChannel, false); DMA_ChannelEnable(obj->spi.dmaOptionsTX.dmaChannel, false);
DMA_ChannelEnable(obj->spi.dmaOptionsRX.dmaChannel, false); DMA_ChannelEnable(obj->spi.dmaOptionsRX.dmaChannel, false);
/* Release the dma channels if they were opportunistically allocated */ /* Release the dma channels if they were opportunistically allocated */
if (obj->spi.dmaOptionsTX.dmaUsageState == DMA_USAGE_TEMPORARY_ALLOCATED) { if (obj->spi.dmaOptionsTX.dmaUsageState == DMA_USAGE_TEMPORARY_ALLOCATED) {
dma_channel_free(obj->spi.dmaOptionsTX.dmaChannel); dma_channel_free(obj->spi.dmaOptionsTX.dmaChannel);
dma_channel_free(obj->spi.dmaOptionsRX.dmaChannel); dma_channel_free(obj->spi.dmaOptionsRX.dmaChannel);
obj->spi.dmaOptionsTX.dmaUsageState = DMA_USAGE_OPPORTUNISTIC; obj->spi.dmaOptionsTX.dmaUsageState = DMA_USAGE_OPPORTUNISTIC;
} }
} else { } else {
// Interrupt implementation: switch off interrupts // Interrupt implementation: switch off interrupts
spi_enable_interrupt(obj, (uint32_t)NULL, false); spi_enable_interrupt(obj, (uint32_t)NULL, false);
} }
// Release sleep mode block // Release sleep mode block
unblockSleepMode(SPI_LEAST_ACTIVE_SLEEPMODE); unblockSleepMode(SPI_LEAST_ACTIVE_SLEEPMODE);
} }