 We can continue with code processing, so we've got two projects for Cortex-M0+, and Cortex-M4, so I can select this link with editor, and then if I would switch from one main.cfl to the other, and the proper main.cfl would be highlighted within the project explorer. Before we will start with code processing, we need to do some modifications with linker files, and in fact linker files for Cortex-M0+. By default, if we are generating the project for both cores, Cortex-M0+, and Cortex-M4, the memory split is organized as following. If I double click on Cortex-M4, I can see that the RAM and flash memory areas are taken from the beginning of those two components. We have half of this total space for Cortex-M4, and the second half is for Cortex-M0+. As you can see now, so I double click on the Cortex-M0+, and you can see that the length of RAM and flash is exactly the same, but we are starting after the Cortex-M4 area. So what we need to do now is to locate the stack for Cortex-M0+, a bit below, because at the end of the RAM area, of total RAM area of the device, so this would be within Cortex-M0+, memory space, we will locate a shared buffer. In this example, we will use a shared buffer which would contain 32 16-bit components, so in total it will use 64 bytes, and we will use as well one byte to inform Cortex-M4 about the status of Cortex-M0+, initialization. So in total we would need 65 bytes for those shared components. This is why I need to decrease this stack and address by 65 bytes. I can save it and then we can continue with code processing. We will start from Cortex-M4, so I go to main.cfile for Cortex-M4. I can close my linker files, there is no need to modify anything within Cortex-M4 on linker file. Okay, so within Cortex-M4 main.cfile, I will start with some private includes, as we will use the manset function and the memcopy function, I would need the string.h header file, so include. Then we need to add some definitions, so for this we've got this private defines section. Two first components will be used as a flux to inform us that Cortex-M0+. has started its activities or not, and the third one, this is the buffer size of the table we will use within our shared buffer. So the next point would be to declare some variables, so we've got this private variable section over here. So then the first point would be to declare our shared buffer of any desired memory space, so it will be address lost 64 bytes of RAM memory space of this microcontroller. And then just before this, we would declare the simple char variable. Next component is receive flag, which will be our temporary variable, and then our buffers. So the square is a buffer word contains the square wave definition, so as you can see it's a mix of maximum and minimum values of 12 bits in this case, but you can use as, of course, bigger values. Okay, then there would be an important global variable which we will use to monitor, let's say the the first component from our shared buffer, and then the channel ID, so it can be any value between zero and the IPCC channel minus one, so it is to activate the identifications coming from inter-processor communication controller. Then we would need to specify as well the transfer trigger, which would be the variable which would inform us that the button has been pressed and the new data came to the buffer and we need to copy it. So we will use this transfer trigger within our external iterates, and some global variable which would be usmx index later on. Okay, so we can continue with further components. So the next point is to declare the function which would be the callback called once the inter-processor communication controller will arise the interrupt, so it is void type. This is up to us how we will specify this callback. We need just to pass this name of the function to the IPCC controller once we activate the notifications, and then we need to implement this callback function for this or use this just not to just use it to copy paste it below. We can use this user code for section and to prevent this we will just set the flag to one. Okay, so we can continue. The next point would be to add some code or implement in fact the callback for the external interrupts. In case you are using previous exercises for dual core, you can reuse existing callbacks. In case you are doing it from the scratch like me at the moment, you can find the name of the callback within this interrupt file, so it.c and here if we go at the end of this file we can see this IRQ handler coming from a terminal interrupts xdi. If I go to the definition of it, so right and button on mouse click then open declaration, we can see this week the definition of the callback or just copy it to our main.c file for Cortex-M4 and we need to implement this function. So within Cortex-M4 we are using external interrupt from channel 1 because we are monitoring pin PA1, so we need to check whether the signal is coming from our pin 1 and if yes, we will just set this transfer trigger variable to 1. In your code you may find as well you can see the toggling of the LEDs of the pins which are controlling LEDs. Those are not necessary for this exercise, so I will just skip it. Then we can continue with the main function, so I scroll up and at the beginning of this Cortex-M4 part I would initialize this CPU2 init done to CPU2 not started. Just check whether this definition not status but started. Okay we can continue. Then within the system init, so in between the initialization of the peripherals we can perform some memory copying, so I need to load the square wave data buffer to my let's say as an initial one to user buffer. So I would use mem copy function and then user buffer, this is the target one and this is the source one and then the size. So I need to size, I will use the size of and I will multiply it by the size of the buffer, so number of the components. That's it, so this is let's say initially copying the square wave to the user buffer, so at the beginning once we run the code we will see the square wave on our variable virtual monitor and then what we need to do next we need to activate notifications from our IPCC module, so I would use it in the following way. So I would call the function how IPCC activate notifications then I need to specify the handler of IPCC then channel ID then the direction, so this is predefined IPCC channel and the direction it won't be Rx because Cortex-M4 will receive the data and our function the callback function which will be called in case of this interrupt occurrence, so it will be re receive callback. Of course we don't need those arguments, we just need the name of the function, so I would delete the rest. Okay and we need to check whether the return value of this function is how okay. If it's how okay it means that everything went correctly and we can continue with further code but if there was an error, so it was not possible to activate the notifications, so something was not okay with the configuration of enable and live with the activation of the IPCC in general, so we should land somewhere for recovery, so I will use here the error handler. Then the next step would be the main while1 loop, so before that we need to check whether our CPU 2, so Cortex-M0 plus is already activated. I will use for this while loop, it would be one line on there, so we'll just check CPU 2, we need to done CPU 2 started, so as the CPU 2 unit done will be equal to CPU 2 started, we can go further. The next point is open this while1 loop. In the while1 loop we start from a simple loop which would copy the content of the user buffer one by one to our mydata global variable, which we will monitor continuously and display its content via single wire viewer. After this we will perform further actions related to IPCC state from let's say this coding. The i has been already initialized at the beginning, mydata is equal to user buffer component and in case we reached the end, we'll set i to zero. So this is the beginning, then after this we'll need to check whether the receive flag has been set. Just to remind you receive flag is set over the IPCC callback, so this receive a callback. So once we receive the notification that IPCC has sent something to us, so this is an information for us that there was some change on the shared buffer, so something new has been copied there and we need to take care of this data. So in fact what we will do, we will copy the content of shared buffer into our user buffer and then we will clear shared buffer. So we'll send our zeros over there and at the end we will send the notification that the data has been received by us. So it would be the information to our Cortex-M0 core that the data has been properly received and there is a new update within this shared buffer. Okay, so we will start from checking whether there was this receive flag set and if yes, we will perform the mem copy. So first would be the target buffer, so our user buffer, then source buffer, so shared buffer, then the number of the data. So we are starting with starting with the size of, that just to be sure that we've got the proper size, so we know that the size of the each component is 16 bits and we will need to multiply by number of the components over there. Next point would be to copy the, to clear in fact and share the buffer with zeros. Then we need to inform our Cortex-M0 plus that the data has been properly received. So it would be how IPCC, notify CPU, and channel direction, it would be our XOR receive and then we need to check whether everything went correctly. So we received how, okay, if it's not the case, we need to land onto the error handler. In case everything went smoothly over this if loop, we need to clear the flag, receive flag. So I need to set it, clear it to zero, yes. Then just after it, we need to check whether there was no button press. So I need to check this transfer trigger variable. In case the button has been pressed, I need to copy, maybe I would just copy to the copy paste thing. So I need to copy the square once again, square to our user buffer. Because on the button, button press coming from Cortex-M4, we are restoring the original content of the user buffer, which is the square wave. And we need to clear the flag at the end. And the last operation within this while one loop of main.c file would be how delay of one second, just not to spam the terminal. Those are the all operations within Cortex-M4. Now it is a time to do some coding within Cortex-M0 plus. But before this, I would just save the changes. So I switched to Cortex-M0 plus main.c file and we'll start with includes. So again, as we are using memset and memcopy functions, I need to include the proper handler. Then I need to project the private defines. Those would be exactly the same like for Cortex-M4. This is why I would do some copy pasting between those two. So exactly the same buffer sizes, we will use the share buffer. We need to specify exactly the same sizes. Then the private variables. So concerning private variables, most of them would be exactly the same. So I would copy this part and change the main components. So we need shared buffer CPU to done because those are shared components. So we need this. We'll have here not receive but transmit flag as will transmit data to the shared buffer. Then we will have user buffer as well. And instead of square, we'll have the sine buffer. I've got it predefined already. So you can copy pasted from the materials as well, just not to retype it. So it is our sine buffer, which would copy to the shared buffer. And then it will be displayed on the variable, which is monitored within Cortex-M4 code execution. And then we will not use my data because this is the variable which is monitored within Cortex-M4 area. We will use as well the channel ID and transfer trigger as well. So we'll keep those until within Cortex-M0 plus. Next point is some private function prototypes. So here we will have a transmit callback. So it will be exactly the same like receive callback within Cortex-M4. So I would copy pasted the declaration over here, but I will change the name. It will be not receive callback, but it will be transmit callback to define this function. Again, within Cortex-M4, within user code 4 area, like previously for Cortex-M4. This time we will set the transmit flag to 1, within this callback. Okay, the next step would be the external interrupt callback definition. So as we are doing it from scratch, so we can find it's a definition of an it.c file. It would be exactly the same like for Cortex-M4. So I would just copy part of this from Cortex-M4 space. I would copy complete function and here we'll have in fact two buttons connected to PA0 and PC6. So channel 0 and channel 6. So it will be channel 0 and we need to check the second condition for channel 6. Of course, we can write it much simpler way, but I'm leaving the spice for possible manipulation of the LEDs or changing the content just to use the opportunity that we've got more buttons here. Okay, transfer trigger to 1, so it will be exactly the same action. Okay, so this is it. Then the next step is within main function. So in the beginning we will clear the shared buffer. So we can use the code from Cortex-M4, this memset, this one, and it can be done really in the beginning. Then the next part is related to inform Cortex-M4 that Cortex-M0 plus has been properly initialized. This is why we will set this shared variable CPU2 in it done to CPU2 started. So once this line would be executed, we will go further over Cortex-M4 code execution. Okay, the next step would be activation of the notification from IPCC. So again, it would be if IPCC activated notifications, IPCC channel ID, and then direction would be PCC channel direction transmit this time, and the callback name it will be transmit callback. Of course, we don't need the complete declaration over here, just the name of the function. And we need to check whether it was successfully executed, so it was how okay if there was not, we need to land within the error handler function. Okay, so this is it in terms of the initialization. Then within while one loop, we need to check whether there was a button press, which is triggering, which is triggering the transfer of a sine buffer into the shared buffer. If it was the case, we need to copy our sine buffer to the shared buffers. I would copy paste this function from Cortex-M4 to here, but I would share this instead of user buffer, I would put here shared buffer. And instead of shared buffer here, I would put sine. So the result of this function would be to copy the sine buffer into the shared buffer once we press the button within Cortex-M0 plus area. Then the next step would be to send a notification over IPCC. So if IPCC notifies CPU and then the handler channel ID and the direction would be transmit this time, and we need to check whether it was successfully executed or not. If not, we need to execute this error handler. If it was successfully executed, we need to clear this transfer trigger variable for the next interrupts from coming from the buttons. Okay, so this is the first part. The second part is related to the transmit flag. So transmit flag would be set in case we received a notification coming from our receiver, so in this case from Cortex-M4. So in case current Cortex-M4 received the data, you remember it receives the data, then it's clearing the shared buffer, and then it's sending the notification. So after this, we will land into the interrupt of IPCC and our transmit flag would be set. This is the information for us that the system is ready, the shared buffer has been used already, and we can upload the new data into the shared buffer. Okay, so we are checking transmit flag if it is set, but in this case we are simplifying it. Those are all components related to Cortex-M0 plus coding, so I would save it. And now we can build the code. Just to make it simple, I would combine those two projects, so I click on right button on mouse and go to properties, then project references, and I can select IPCC Cortex-M4, apply and close, and now if I press this build, it will build automatically first Cortex-M4, which is connected to our project, and then the next step the Cortex-M0 plus will be built. Okay, so now we are ready to configure a debug session, and after this we will start the debug session and check whether the application is working correctly. Thank you for watching this video.