]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M4F_M0_LPC43xx_Keil/M4/ParTest.c
b4df4b738054c49c88f6d03e1356446c21b3ca41
[freertos] / FreeRTOS / Demo / CORTEX_M4F_M0_LPC43xx_Keil / M4 / ParTest.c
1 /*\r
2  * FreeRTOS Kernel V10.2.1\r
3  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software.\r
14  *\r
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21  *\r
22  * http://www.FreeRTOS.org\r
23  * http://aws.amazon.com/freertos\r
24  *\r
25  * 1 tab == 4 spaces!\r
26  */\r
27 \r
28 /*-----------------------------------------------------------\r
29  * Normally, a demo application would define ParTest (parallel port test)\r
30  * functions to write to an LED.  In this case, four '*' symbols that are\r
31  * output to the debug printf() port are used to simulate LED outputs.\r
32  *-----------------------------------------------------------*/\r
33 \r
34 /* Standard includes. */\r
35 #include <stdio.h>\r
36 #include <string.h>\r
37 \r
38 /* Library includes. */\r
39 #include "lpc43xx_i2c.h"\r
40 \r
41 /* Kernel includes. */\r
42 #include "FreeRTOS.h"\r
43 #include "task.h"\r
44 #include "queue.h"\r
45 \r
46 /* Standard demo include. */\r
47 #include "partest.h"\r
48 \r
49 /* The number of LED outputs. */\r
50 #define partstMAX_LEDS 4\r
51 \r
52 /* Commands written to the PCA9502. */\r
53 #define partstIO_WRITE_COMMAND  ( ( unsigned char ) ( 0x0BU << 3U ) )\r
54 #define partstIO_DIR_COMMAND    ( ( unsigned char ) ( 0x0AU << 3U ) )\r
55 #define partstSLAVE_ADDRESS             ( ( unsigned char ) ( 0x9AU >> 1U ) )\r
56 \r
57 /* Just defines the length of the queue used to pass toggle commands to the I2C\r
58 gatekeeper task. */\r
59 #define partstLED_COMMAND_QUEUE_LENGTH  ( 6 )\r
60 /*-----------------------------------------------------------*/\r
61 \r
62 /*\r
63  * The LEDs are connected to an I2C port expander.  Therefore, writing to an\r
64  * LED takes longer than might be expected if the LED was connected directly\r
65  * to a GPIO pin.  As several tasks, and a timer, toggle LEDs, it is convenient\r
66  * to use a gatekeeper task to ensure access is both mutually exclusive and\r
67  * serialised.  Tasks other than this gatekeeper task must not access the I2C\r
68  * port directly.\r
69  */\r
70 static void prvI2CGateKeeperTask( void *pvParameters );\r
71 \r
72 /* The queue used to communicate toggle commands with the I2C gatekeeper\r
73 task. */\r
74 static QueueHandle_t xI2CCommandQueue = NULL;\r
75 /*-----------------------------------------------------------*/\r
76 \r
77 void vParTestInitialise( void )\r
78 {\r
79 unsigned char ucBuffer[ 2 ];\r
80 I2C_M_SETUP_Type xI2CMessage;\r
81 \r
82         /* The LEDs are on an I2C IO expander.  Initialise the I2C interface. */\r
83         I2C_Init( LPC_I2C0, 300000 );\r
84         I2C_Cmd( LPC_I2C0, ENABLE );\r
85 \r
86         /* GPIO0-GPIO2 to output. */\r
87         ucBuffer[ 0 ] = partstIO_DIR_COMMAND;\r
88         ucBuffer[ 1 ] = 0x0f;\r
89         xI2CMessage.sl_addr7bit = partstSLAVE_ADDRESS;\r
90         xI2CMessage.tx_data = ucBuffer ;\r
91         xI2CMessage.tx_length = sizeof( ucBuffer );\r
92         xI2CMessage.rx_data = NULL;\r
93         xI2CMessage.rx_length = 0;\r
94         xI2CMessage.retransmissions_max = 3;\r
95         I2C_MasterTransferData( LPC_I2C0, &xI2CMessage, I2C_TRANSFER_POLLING );\r
96 \r
97         /* Create the mutex used to guard access to the I2C bus. */\r
98         xI2CCommandQueue = xQueueCreate( partstLED_COMMAND_QUEUE_LENGTH, sizeof( unsigned char ) );\r
99         configASSERT( xI2CCommandQueue );\r
100 \r
101         /* Create the I2C gatekeeper task itself. */\r
102         xTaskCreate( prvI2CGateKeeperTask, "I2C", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );\r
103 }\r
104 /*-----------------------------------------------------------*/\r
105 \r
106 void vParTestToggleLED( unsigned long ulLED )\r
107 {\r
108 unsigned char ucLED = ( unsigned char ) ulLED;\r
109 \r
110         /* Only the gatekeeper task will actually access the I2C port, so send the\r
111         toggle request to the gatekeeper task.  A block time of zero is used as\r
112         this function is called by a software timer callback. */\r
113         xQueueSend( xI2CCommandQueue, &ucLED, 0UL );\r
114 }\r
115 /*-----------------------------------------------------------*/\r
116 \r
117 static void prvI2CGateKeeperTask( void *pvParameters )\r
118 {\r
119 unsigned char ucBuffer[ 2 ], ucLED;\r
120 static unsigned char ucLEDState = 0xffU;\r
121 static I2C_M_SETUP_Type xI2CMessage; /* Static so it is not on the stack as this is called from task code. */\r
122 \r
123         /* Just to remove compiler warnings. */\r
124         ( void ) pvParameters;\r
125 \r
126         for( ;; )\r
127         {\r
128                 /* Wait for the next command. */\r
129                 xQueueReceive( xI2CCommandQueue, &ucLED, portMAX_DELAY );\r
130 \r
131                 /* Only this task is allowed to touch the I2C port, so there is no need\r
132                 for additional mutual exclusion. */\r
133                 if( ucLED < partstMAX_LEDS )\r
134                 {\r
135                         /* Which bit is being manipulated? */\r
136                         ucLED = 0x01 << ucLED;\r
137 \r
138                         /* Is the bit currently set or clear? */\r
139                         if( ( ucLEDState & ucLED ) == 0U )\r
140                         {\r
141                                 ucLEDState |= ucLED;\r
142                         }\r
143                         else\r
144                         {\r
145                                 ucLEDState &= ~ucLED;\r
146                         }\r
147 \r
148                         ucBuffer[ 0 ] = partstIO_WRITE_COMMAND;\r
149                         ucBuffer[ 1 ] = ucLEDState;\r
150 \r
151                         xI2CMessage.sl_addr7bit = partstSLAVE_ADDRESS;\r
152                         xI2CMessage.tx_data = ucBuffer ;\r
153                         xI2CMessage.tx_length = sizeof( ucBuffer );\r
154                         xI2CMessage.rx_data = NULL;\r
155                         xI2CMessage.rx_length = 0;\r
156                         xI2CMessage.retransmissions_max = 3;\r
157                         I2C_MasterTransferData( LPC_I2C0, &xI2CMessage, I2C_TRANSFER_POLLING );\r
158                 }\r
159         }\r
160 }\r
161 /*-----------------------------------------------------------*/\r
162 \r